From 875789c7756941296306b6781142f62d0d5e5fbe Mon Sep 17 00:00:00 2001 From: Jason Gross Date: Tue, 19 Jun 2018 00:03:37 -0400 Subject: Montgomery reduction in new pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After | File Name | Before || Change | % Change -------------------------------------------------------------------------------------------------------- 18m19.81s | Total | 14m31.66s || +3m48.14s | +26.17% -------------------------------------------------------------------------------------------------------- 4m04.77s | Experiments/NewPipeline/Toplevel1 | 1m38.04s || +2m26.73s | +149.66% 5m12.44s | Experiments/NewPipeline/Rewriter | 4m20.00s || +0m52.43s | +20.16% 1m26.58s | Experiments/NewPipeline/Arithmetic | 0m55.51s || +0m31.07s | +55.97% 5m44.19s | Experiments/NewPipeline/SlowPrimeSynthesisExamples | 5m45.62s || -0m01.43s | -0.41% 1m29.48s | Experiments/NewPipeline/Toplevel2 | 1m29.73s || -0m00.25s | -0.27% 0m12.75s | Experiments/NewPipeline/CStringification | 0m12.71s || +0m00.03s | +0.31% 0m01.32s | Experiments/NewPipeline/GENERATEDIdentifiersWithoutTypes | 0m01.20s || +0m00.12s | +10.00% 0m01.31s | Experiments/NewPipeline/CLI | 0m01.33s || -0m00.02s | -1.50% 0m01.18s | Experiments/NewPipeline/StandaloneHaskellMain | 0m01.22s || -0m00.04s | -3.27% 0m01.12s | Experiments/NewPipeline/StandaloneOCamlMain | 0m01.21s || -0m00.08s | -7.43% 0m01.11s | Experiments/NewPipeline/Language | 0m01.14s || -0m00.02s | -2.63% 0m01.08s | Experiments/NewPipeline/AbstractInterpretation | 0m01.16s || -0m00.07s | -6.89% 0m00.90s | Experiments/NewPipeline/MiscCompilerPasses | 0m00.87s || +0m00.03s | +3.44% 0m00.74s | Experiments/NewPipeline/CompilersTestCases | 0m01.03s || -0m00.29s | -28.15% 0m00.44s | Experiments/NewPipeline/AbstractInterpretationProofs | 0m00.40s || +0m00.03s | +9.99% 0m00.41s | Experiments/NewPipeline/UnderLets | 0m00.50s || -0m00.09s | -18.00% After | File Name | Before || Change | % Change ------------------------------------------------------------------------------------------------------------------------- 107m58.13s | Total | 102m35.85s || +5m22.27s | +5.23% ------------------------------------------------------------------------------------------------------------------------- 4m32.58s | Experiments/NewPipeline/Toplevel1 | 1m50.07s || +2m42.50s | +147.64% N/A | ─abstract | 1m54.94s || -1m54.93s | -100.00% 1m54.19s | Specific/X2448/Karatsuba/C64/femul | N/A || +1m54.18s | ∞ 7m58.19s | Experiments/NewPipeline/Rewriter | 6m45.32s || +1m12.87s | +17.97% 2m13.30s | Experiments/NewPipeline/Arithmetic | 1m34.69s || +0m38.61s | +40.77% 5m30.50s | Curves/Weierstrass/Projective | 5m09.44s || +0m21.06s | +6.80% 12m00.73s | Curves/Weierstrass/AffineProofs | 11m43.07s || +0m17.65s | +2.51% 0m54.76s | Compilers/Z/ArithmeticSimplifierWf | 0m43.68s || +0m11.07s | +25.36% 10m06.67s | Experiments/SimplyTypedArithmetic | 9m58.44s || +0m08.22s | +1.37% 1m05.15s | Arithmetic/Karatsuba | 0m58.76s || +0m06.39s | +10.87% 0m41.15s | Specific/NISTP256/AMD128/femul | 0m47.16s || -0m06.00s | -12.74% 5m46.39s | Experiments/NewPipeline/SlowPrimeSynthesisExamples | 5m52.03s || -0m05.63s | -1.60% 2m14.99s | Specific/X25519/C64/ladderstep | 2m20.69s || -0m05.69s | -4.05% 0m48.64s | Specific/X25519/C32/freeze | 0m43.24s || +0m05.39s | +12.48% 0m26.80s | Specific/X25519/C64/fesquare | 0m20.83s || +0m05.97s | +28.66% 0m27.22s | Specific/X25519/C32/feadd | 0m31.34s || -0m04.12s | -13.14% 0m23.26s | Specific/NISTP256/AMD64/fenz | 0m19.10s || +0m04.16s | +21.78% 0m21.24s | Specific/NISTP256/AMD128/fesub | 0m25.24s || -0m04.00s | -15.84% 3m38.32s | Curves/Montgomery/XZProofs | 3m34.65s || +0m03.66s | +1.70% 1m14.93s | Compilers/Z/ArithmeticSimplifierInterp | 1m11.88s || +0m03.05s | +4.24% 0m16.16s | Arithmetic/Saturated/MontgomeryAPI | 0m12.26s || +0m03.90s | +31.81% 0m07.54s | Compilers/Z/Bounds/InterpretationLemmas/PullCast | 0m10.65s || -0m03.11s | -29.20% 2m29.22s | Specific/NISTP256/AMD64/femul | 2m31.90s || -0m02.68s | -1.76% 2m02.88s | Compilers/Named/MapCastInterp | 2m00.84s || +0m02.03s | +1.68% 1m54.19s | Curves/Weierstrass/Jacobian | 1m52.12s || +0m02.06s | +1.84% 1m30.98s | Specific/X25519/C32/femul | 1m28.28s || +0m02.70s | +3.05% 1m30.59s | Experiments/NewPipeline/Toplevel2 | 1m32.97s || -0m02.37s | -2.55% 1m20.73s | Demo | 1m18.51s || +0m02.21s | +2.82% 1m07.85s | Specific/X25519/C32/fesquare | 1m09.85s || -0m02.00s | -2.86% 0m31.78s | Specific/X25519/C32/fesub | 0m34.25s || -0m02.46s | -7.21% 0m31.18s | Arithmetic/Core | 0m33.92s || -0m02.74s | -8.07% 0m26.24s | Compilers/Z/CNotations | 0m28.35s || -0m02.11s | -7.44% 0m22.15s | Specific/X25519/C64/fecarry | 0m19.73s || +0m02.41s | +12.26% 0m21.61s | Arithmetic/Saturated/AddSub | 0m18.87s || +0m02.73s | +14.52% 0m21.58s | Specific/X25519/C64/fesub | 0m19.14s || +0m02.43s | +12.74% 0m14.37s | Arithmetic/Saturated/Core | 0m16.57s || -0m02.20s | -13.27% 2m57.98s | Curves/Montgomery/AffineProofs | 2m59.71s || -0m01.73s | -0.96% 1m46.10s | Spec/Test/X25519 | 1m47.38s || -0m01.28s | -1.19% 0m40.69s | Primitives/EdDSARepChange | 0m42.34s || -0m01.65s | -3.89% 0m40.29s | Specific/X25519/C32/fecarry | 0m42.21s || -0m01.92s | -4.54% 0m33.64s | Arithmetic/MontgomeryReduction/WordByWord/Abstract/Dependent/Proofs | 0m31.88s || +0m01.76s | +5.52% 0m31.96s | Specific/NISTP256/AMD64/feadd | 0m30.27s || +0m01.69s | +5.58% 0m23.14s | Specific/NISTP256/AMD128/feadd | 0m24.34s || -0m01.19s | -4.93% 0m18.76s | Specific/NISTP256/AMD128/feopp | 0m20.20s || -0m01.43s | -7.12% 0m18.62s | Compilers/Z/Syntax/Equality | 0m17.08s || +0m01.54s | +9.01% 0m15.06s | Util/ZUtil | 0m13.95s || +0m01.11s | +7.95% 0m14.13s | LegacyArithmetic/ArchitectureToZLikeProofs | 0m12.75s || +0m01.38s | +10.82% 0m12.43s | Compilers/Named/CompileInterpSideConditions | 0m10.85s || +0m01.58s | +14.56% 0m10.06s | Specific/NISTP256/AMD64/Synthesis | 0m11.31s || -0m01.25s | -11.05% 0m08.04s | Arithmetic/BarrettReduction/Generalized | 0m09.68s || -0m01.64s | -16.94% 0m06.25s | Specific/Framework/ArithmeticSynthesis/Montgomery | 0m05.18s || +0m01.07s | +20.65% 0m05.70s | LegacyArithmetic/InterfaceProofs | 0m07.21s || -0m01.50s | -20.94% 0m05.50s | Compilers/Z/Bounds/Pipeline/Definition | 0m06.57s || -0m01.07s | -16.28% 0m04.54s | LegacyArithmetic/Double/Proofs/Decode | 0m05.59s || -0m01.04s | -18.78% 0m04.32s | Compilers/Z/ArithmeticSimplifier | 0m05.36s || -0m01.04s | -19.40% 0m02.15s | Specific/Framework/ArithmeticSynthesis/Defaults | 0m03.49s || -0m01.34s | -38.39% N/A | Coqprime/PrimalityTest/EGroup | 0m01.32s || -0m01.32s | -100.00% N/A | Coqprime/Z/ZCAux | 0m01.08s || -0m01.08s | -100.00% 1m21.20s | Compilers/Z/Named/RewriteAddToAdcInterp | 1m21.80s || -0m00.59s | -0.73% 0m43.90s | Spec/Ed25519 | 0m43.40s || +0m00.50s | +1.15% 0m40.68s | Compilers/CommonSubexpressionEliminationWf | 0m40.81s || -0m00.13s | -0.31% 0m34.84s | Specific/NISTP256/AMD64/fesub | 0m33.87s || +0m00.97s | +2.86% 0m32.80s | Specific/X25519/C64/femul | 0m31.99s || +0m00.80s | +2.53% 0m30.69s | Curves/Edwards/XYZT/Basic | 0m30.20s || +0m00.49s | +1.62% 0m27.90s | Compilers/Named/MapCastWf | 0m27.10s || +0m00.79s | +2.95% 0m27.80s | Specific/X25519/C32/Synthesis | 0m28.14s || -0m00.33s | -1.20% 0m27.70s | bbv/Word | 0m27.58s || +0m00.12s | +0.43% 0m26.05s | Specific/NISTP256/AMD64/feopp | 0m26.52s || -0m00.46s | -1.77% 0m25.59s | Specific/X25519/C64/freeze | 0m25.20s || +0m00.39s | +1.54% 0m25.40s | Curves/Edwards/AffineProofs | 0m24.70s || +0m00.69s | +2.83% 0m22.94s | Compilers/Named/ContextProperties/NameUtil | 0m23.02s || -0m00.07s | -0.34% 0m22.14s | Algebra/Field | 0m21.80s || +0m00.33s | +1.55% 0m21.99s | Specific/NISTP256/AMD128/fenz | 0m21.30s || +0m00.68s | +3.23% 0m21.68s | Compilers/Named/ContextProperties/SmartMap | 0m22.15s || -0m00.46s | -2.12% 0m20.08s | Experiments/NewPipeline/CStringification | 0m19.13s || +0m00.94s | +4.96% 0m19.91s | Arithmetic/MontgomeryReduction/WordByWord/Abstract/Proofs | 0m19.60s || +0m00.30s | +1.58% 0m19.57s | Specific/X25519/C64/feadd | 0m19.12s || +0m00.44s | +2.35% 0m17.58s | Primitives/MxDHRepChange | 0m17.59s || -0m00.01s | -0.05% 0m17.56s | LegacyArithmetic/Double/Proofs/Multiply | 0m18.42s || -0m00.86s | -4.66% 0m15.44s | Arithmetic/MontgomeryReduction/Proofs | 0m14.96s || +0m00.47s | +3.20% 0m14.54s | Specific/X2448/Karatsuba/C64/Synthesis | 0m14.15s || +0m00.38s | +2.75% 0m14.18s | LegacyArithmetic/Double/Proofs/ShiftRightDoubleWordImmediate | 0m13.57s || +0m00.60s | +4.49% 0m13.88s | Algebra/Ring | 0m13.58s || +0m00.30s | +2.20% 0m13.44s | LegacyArithmetic/Double/Proofs/SpreadLeftImmediate | 0m13.40s || +0m00.03s | +0.29% 0m11.85s | LegacyArithmetic/Double/Proofs/RippleCarryAddSub | 0m11.82s || +0m00.02s | +0.25% 0m11.46s | Compilers/InlineConstAndOpWf | 0m11.58s || -0m00.11s | -1.03% 0m11.43s | Compilers/Named/RegisterAssignInterp | 0m11.26s || +0m00.16s | +1.50% 0m11.29s | Arithmetic/BarrettReduction/RidiculousFish | 0m10.73s || +0m00.55s | +5.21% 0m10.27s | Arithmetic/Saturated/MulSplit | 0m10.24s || +0m00.02s | +0.29% 0m10.07s | Util/ZUtil/ZSimplify/Autogenerated | 0m09.74s || +0m00.33s | +3.38% 0m09.72s | Util/FixedWordSizesEquality | 0m10.08s || -0m00.35s | -3.57% 0m09.25s | LegacyArithmetic/Pow2BaseProofs | 0m09.10s || +0m00.15s | +1.64% 0m08.74s | Compilers/InlineWf | 0m08.45s || +0m00.29s | +3.43% 0m08.65s | Util/FsatzAutoLemmas | 0m08.94s || -0m00.28s | -3.24% 0m08.30s | Util/ListUtil | 0m08.37s || -0m00.06s | -0.83% 0m08.12s | Compilers/LinearizeWf | 0m08.43s || -0m00.31s | -3.67% 0m07.92s | Specific/X25519/C64/Synthesis | 0m07.90s || +0m00.01s | +0.25% 0m07.72s | Arithmetic/BarrettReduction/HAC | 0m07.57s || +0m00.14s | +1.98% 0m07.64s | Compilers/Z/HexNotationConstants | 0m08.06s || -0m00.42s | -5.21% 0m07.62s | Util/ZUtil/Modulo | 0m07.58s || +0m00.04s | +0.52% 0m07.54s | Curves/Edwards/Pre | 0m07.92s || -0m00.37s | -4.79% 0m07.34s | Compilers/WfProofs | 0m06.72s || +0m00.62s | +9.22% 0m06.86s | Algebra/Field_test | 0m07.34s || -0m00.47s | -6.53% 0m06.80s | Compilers/Z/BinaryNotationConstants | 0m06.76s || +0m00.04s | +0.59% 0m06.00s | LegacyArithmetic/Double/Proofs/ShiftRight | 0m06.00s || +0m00.00s | +0.00% 0m05.58s | Compilers/Named/CompileWf | 0m05.85s || -0m00.26s | -4.61% 0m05.58s | Curves/Montgomery/Affine | 0m06.52s || -0m00.93s | -14.41% 0m05.31s | Specific/NISTP256/AMD128/Synthesis | 0m04.90s || +0m00.40s | +8.36% 0m05.17s | LegacyArithmetic/Double/Proofs/ShiftLeft | 0m05.14s || +0m00.03s | +0.58% 0m05.14s | Arithmetic/ModularArithmeticTheorems | 0m05.32s || -0m00.18s | -3.38% 0m04.93s | LegacyArithmetic/ZBoundedZ | 0m05.51s || -0m00.58s | -10.52% 0m04.90s | Compilers/Z/Bounds/InterpretationLemmas/IsBoundedBy | 0m05.62s || -0m00.71s | -12.81% 0m04.76s | Compilers/TestCase | 0m04.72s || +0m00.04s | +0.84% 0m04.74s | Arithmetic/MontgomeryReduction/WordByWord/Proofs | 0m05.51s || -0m00.76s | -13.97% 0m04.48s | Util/WordUtil | 0m04.51s || -0m00.02s | -0.66% 0m04.32s | Spec/MontgomeryCurve | 0m03.77s || +0m00.55s | +14.58% 0m04.13s | Compilers/InlineInterp | 0m04.29s || -0m00.16s | -3.72% 0m04.09s | Util/ZUtil/Div | 0m03.82s || +0m00.27s | +7.06% 0m03.96s | LegacyArithmetic/BarretReduction | 0m04.49s || -0m00.53s | -11.80% 0m03.93s | Compilers/EtaWf | 0m03.94s || -0m00.00s | -0.25% 0m03.81s | Compilers/Named/ContextProperties | 0m04.33s || -0m00.52s | -12.00% 0m03.69s | Specific/NISTP256/FancyMachine256/Montgomery | 0m03.77s || -0m00.08s | -2.12% 0m03.65s | Algebra/Group | 0m03.95s || -0m00.30s | -7.59% 0m03.63s | Arithmetic/Saturated/Freeze | 0m03.63s || +0m00.00s | +0.00% 0m03.54s | Compilers/Z/RewriteAddToAdcInterp | 0m03.26s || +0m00.28s | +8.58% 0m03.49s | Compilers/Named/CompileInterp | 0m03.55s || -0m00.05s | -1.69% 0m03.47s | Compilers/Z/Bounds/Relax | 0m03.12s || +0m00.35s | +11.21% 0m03.31s | Specific/NISTP256/FancyMachine256/Barrett | 0m03.70s || -0m00.39s | -10.54% 0m03.21s | Compilers/Named/NameUtilProperties | 0m03.16s || +0m00.04s | +1.58% 0m03.15s | Specific/NISTP256/FancyMachine256/Core | 0m02.96s || +0m00.18s | +6.41% 0m03.14s | Compilers/Named/ContextProperties/Proper | 0m03.67s || -0m00.52s | -14.44% 0m03.06s | Compilers/Z/JavaNotations | 0m03.18s || -0m00.12s | -3.77% 0m03.00s | Compilers/CommonSubexpressionEliminationProperties | 0m02.91s || +0m00.08s | +3.09% 0m02.94s | Compilers/WfReflective | 0m02.18s || +0m00.75s | +34.86% 0m02.91s | Util/ZUtil/Quot | 0m02.24s || +0m00.67s | +29.91% 0m02.80s | Arithmetic/CoreUnfolder | 0m02.53s || +0m00.27s | +10.67% 0m02.78s | Util/ZUtil/AddGetCarry | 0m02.78s || +0m00.00s | +0.00% 0m02.67s | Spec/WeierstrassCurve | 0m02.45s || +0m00.21s | +8.97% 0m02.54s | Compilers/Named/WfFromUnit | 0m02.61s || -0m00.06s | -2.68% 0m02.51s | Specific/Framework/ReificationTypes | 0m02.57s || -0m00.06s | -2.33% 0m02.45s | Arithmetic/BarrettReduction/Wikipedia | 0m02.72s || -0m00.27s | -9.92% 0m02.41s | Specific/Framework/OutputType | 0m02.49s || -0m00.08s | -3.21% 0m02.35s | Compilers/Named/InterpretToPHOASWf | 0m02.44s || -0m00.08s | -3.68% 0m02.31s | Util/NatUtil | 0m02.31s || +0m00.00s | +0.00% 0m02.26s | LegacyArithmetic/MontgomeryReduction | 0m02.40s || -0m00.14s | -5.83% 0m02.25s | Util/ZUtil/Pow2Mod | 0m02.19s || +0m00.06s | +2.73% 0m02.21s | Specific/Framework/ArithmeticSynthesis/Base | 0m02.23s || -0m00.02s | -0.89% 0m02.20s | Curves/Edwards/XYZT/Precomputed | 0m02.07s || +0m00.13s | +6.28% 0m02.16s | Arithmetic/PrimeFieldTheorems | 0m01.58s || +0m00.58s | +36.70% 0m02.16s | LegacyArithmetic/Double/Proofs/BitwiseOr | 0m02.20s || -0m00.04s | -1.81% 0m02.12s | LegacyArithmetic/Double/Proofs/LoadImmediate | 0m02.20s || -0m00.08s | -3.63% 0m02.06s | Util/QUtil | 0m02.08s || -0m00.02s | -0.96% 0m02.03s | Compilers/Relations | 0m02.31s || -0m00.28s | -12.12% 0m02.02s | Experiments/NewPipeline/GENERATEDIdentifiersWithoutTypes | 0m01.99s || +0m00.03s | +1.50% 0m02.00s | Util/Tuple | 0m01.75s || +0m00.25s | +14.28% 0m01.87s | Algebra/ScalarMult | 0m01.76s || +0m00.11s | +6.25% 0m01.82s | Arithmetic/Saturated/CoreUnfolder | 0m01.76s || +0m00.06s | +3.40% 0m01.82s | Experiments/NewPipeline/StandaloneOCamlMain | 0m01.43s || +0m00.39s | +27.27% 0m01.82s | LegacyArithmetic/BaseSystemProofs | 0m01.98s || -0m00.15s | -8.08% 0m01.80s | Compilers/LinearizeInterp | 0m01.76s || +0m00.04s | +2.27% 0m01.80s | Experiments/NewPipeline/StandaloneHaskellMain | 0m01.47s || +0m00.33s | +22.44% 0m01.76s | Compilers/MultiSizeTest | 0m01.78s || -0m00.02s | -1.12% 0m01.76s | Compilers/Z/RewriteAddToAdcWf | 0m01.70s || +0m00.06s | +3.52% 0m01.76s | Experiments/NewPipeline/Language | 0m01.67s || +0m00.09s | +5.38% 0m01.72s | Experiments/NewPipeline/AbstractInterpretation | 0m01.72s || +0m00.00s | +0.00% 0m01.66s | Util/ZUtil/Stabilization | 0m01.55s || +0m00.10s | +7.09% 0m01.64s | Specific/Framework/IntegrationTestDisplayCommon | 0m01.75s || -0m00.11s | -6.28% 0m01.58s | Compilers/Named/InterpretToPHOASInterp | 0m01.59s || -0m00.01s | -0.62% 0m01.54s | Util/ZUtil/Modulo/PullPush | 0m01.26s || +0m00.28s | +22.22% 0m01.51s | Util/NumTheoryUtil | 0m01.33s || +0m00.17s | +13.53% 0m01.51s | Util/ZRange/CornersMonotoneBounds | 0m01.88s || -0m00.36s | -19.68% 0m01.45s | Arithmetic/Saturated/UniformWeight | 0m01.30s || +0m00.14s | +11.53% 0m01.42s | Specific/Framework/ArithmeticSynthesis/Karatsuba | 0m01.49s || -0m00.07s | -4.69% 0m01.37s | Compilers/Z/CommonSubexpressionElimination | 0m01.45s || -0m00.07s | -5.51% 0m01.36s | Compilers/MapCastByDeBruijnInterp | 0m01.32s || +0m00.04s | +3.03% 0m01.34s | Specific/X25519/C32/CurveParameters | 0m01.25s || +0m00.09s | +7.20% 0m01.32s | Compilers/Z/Syntax/Util | 0m01.12s || +0m00.19s | +17.85% 0m01.32s | Specific/Framework/ArithmeticSynthesis/Freeze | 0m00.90s || +0m00.42s | +46.66% 0m01.31s | Algebra/IntegralDomain | 0m01.31s || +0m00.00s | +0.00% 0m01.31s | Arithmetic/Saturated/MulSplitUnfolder | 0m01.32s || -0m00.01s | -0.75% 0m01.31s | Compilers/Named/CompileProperties | 0m01.30s || +0m00.01s | +0.76% 0m01.31s | Util/ZUtil/Testbit | 0m01.66s || -0m00.34s | -21.08% 0m01.30s | Compilers/Z/Bounds/Pipeline/ReflectiveTactics | 0m01.29s || +0m00.01s | +0.77% 0m01.30s | Experiments/NewPipeline/CLI | 0m01.28s || +0m00.02s | +1.56% 0m01.27s | bbv/NatLib | 0m01.06s || +0m00.20s | +19.81% 0m01.26s | Arithmetic/Saturated/FreezeUnfolder | 0m00.84s || +0m00.42s | +50.00% 0m01.24s | Specific/Framework/IntegrationTestTemporaryMiscCommon | 0m01.31s || -0m00.07s | -5.34% 0m01.22s | Util/ZUtil/EquivModulo | 0m01.16s || +0m00.06s | +5.17% 0m01.21s | Specific/Framework/MontgomeryReificationTypes | 0m01.19s || +0m00.02s | +1.68% 0m01.19s | Specific/Framework/ReificationTypesPackage | 0m00.85s || +0m00.34s | +40.00% 0m01.19s | Specific/Framework/SynthesisFramework | 0m01.04s || +0m00.14s | +14.42% 0m01.17s | Experiments/NewPipeline/MiscCompilerPasses | 0m01.25s || -0m00.08s | -6.40% 0m01.15s | Compilers/Named/AListContext | 0m01.08s || +0m00.06s | +6.48% 0m01.14s | Arithmetic/MontgomeryReduction/WordByWord/Definition | 0m01.18s || -0m00.04s | -3.38% 0m01.14s | Arithmetic/Saturated/Wrappers | 0m00.85s || +0m00.28s | +34.11% 0m01.14s | Specific/Framework/ArithmeticSynthesis/HelperTactics | 0m01.12s || +0m00.01s | +1.78% 0m01.14s | Util/PartiallyReifiedProp | 0m01.12s || +0m00.01s | +1.78% 0m01.14s | Util/ZRange/BasicLemmas | 0m01.26s || -0m00.12s | -9.52% 0m01.13s | Specific/Framework/ArithmeticSynthesis/DefaultsPackage | 0m00.86s || +0m00.26s | +31.39% 0m01.12s | Compilers/InlineConstAndOpInterp | 0m00.90s || +0m00.22s | +24.44% 0m01.12s | Compilers/WfInversion | 0m01.18s || -0m00.05s | -5.08% 0m01.12s | Specific/Framework/ArithmeticSynthesis/FreezePackage | 0m00.77s || +0m00.35s | +45.45% 0m01.11s | Specific/Framework/ArithmeticSynthesis/SquareFromMul | 0m01.13s || -0m00.01s | -1.76% 0m01.08s | Compilers/Named/FMapContext | 0m01.27s || -0m00.18s | -14.96% 0m01.08s | Curves/Montgomery/AffineInstances | 0m01.16s || -0m00.07s | -6.89% 0m01.08s | Util/ZUtil/Peano | 0m01.10s || -0m00.02s | -1.81% 0m01.08s | Util/ZUtil/ZSimplify/Simple | 0m00.88s || +0m00.20s | +22.72% 0m01.07s | Specific/Framework/ArithmeticSynthesis/BasePackage | 0m01.14s || -0m00.06s | -6.14% 0m01.06s | LegacyArithmetic/Double/Proofs/SelectConditional | 0m01.09s || -0m00.03s | -2.75% 0m01.04s | Compilers/InterpByIsoProofs | 0m01.16s || -0m00.11s | -10.34% 0m01.03s | Compilers/SmartMap | 0m01.04s || -0m00.01s | -0.96% 0m01.03s | Compilers/Z/Bounds/Pipeline | 0m00.85s || +0m00.18s | +21.17% 0m01.03s | Util/ZUtil/Morphisms | 0m01.23s || -0m00.19s | -16.26% 0m01.02s | Curves/Montgomery/XZ | 0m00.96s || +0m00.06s | +6.25% 0m01.01s | Arithmetic/Saturated/WrappersUnfolder | 0m01.59s || -0m00.58s | -36.47% 0m01.01s | Compilers/Named/InterpSideConditionsInterp | 0m01.12s || -0m00.11s | -9.82% 0m01.00s | Util/CPSUtil | 0m01.09s || -0m00.09s | -8.25% 0m00.99s | Compilers/CommonSubexpressionElimination | 0m00.78s || +0m00.20s | +26.92% 0m00.96s | Util/ZUtil/CC | 0m00.89s || +0m00.06s | +7.86% 0m00.95s | Compilers/MapBaseTypeWf | 0m00.78s || +0m00.16s | +21.79% 0m00.95s | Specific/Framework/ArithmeticSynthesis/LadderstepPackage | 0m01.10s || -0m00.15s | -13.63% 0m00.94s | Compilers/Z/Reify | 0m00.96s || -0m00.02s | -2.08% 0m00.93s | Compilers/Z/Bounds/Pipeline/Glue | 0m00.88s || +0m00.05s | +5.68% 0m00.92s | Arithmetic/Saturated/UniformWeightInstances | 0m01.10s || -0m00.18s | -16.36% 0m00.92s | Compilers/Z/Bounds/MapCastByDeBruijnInterp | 0m00.90s || +0m00.02s | +2.22% 0m00.89s | Compilers/Z/MapCastByDeBruijnInterp | 0m00.87s || +0m00.02s | +2.29% 0m00.89s | Curves/Weierstrass/Affine | 0m00.79s || +0m00.09s | +12.65% 0m00.89s | Specific/Framework/ArithmeticSynthesis/KaratsubaPackage | 0m00.76s || +0m00.13s | +17.10% 0m00.89s | Util/ZUtil/Tactics/RewriteModSmall | 0m01.13s || -0m00.23s | -21.23% 0m00.88s | Compilers/Named/WfInterp | 0m00.76s || +0m00.12s | +15.78% 0m00.88s | Compilers/Z/ArithmeticSimplifierUtil | 0m00.80s || +0m00.07s | +9.99% 0m00.88s | Util/Decidable | 0m00.81s || +0m00.06s | +8.64% 0m00.88s | Util/Factorize | 0m00.92s || -0m00.04s | -4.34% 0m00.88s | Util/ZUtil/Rshi | 0m01.11s || -0m00.23s | -20.72% 0m00.86s | Compilers/Z/Bounds/RoundUpLemmas | 0m00.90s || -0m00.04s | -4.44% 0m00.86s | LegacyArithmetic/Double/Core | 0m00.90s || -0m00.04s | -4.44% 0m00.85s | Arithmetic/ModularArithmeticPre | 0m00.82s || +0m00.03s | +3.65% N/A | Coqprime/Z/ZSum | 0m00.85s || -0m00.85s | -100.00% 0m00.85s | Specific/Framework/ArithmeticSynthesis/Ladderstep | 0m01.10s || -0m00.25s | -22.72% 0m00.84s | Compilers/Z/Bounds/InterpretationLemmas/Tactics | 0m00.88s || -0m00.04s | -4.54% 0m00.84s | Compilers/Z/Bounds/MapCastByDeBruijnWf | 0m00.85s || -0m00.01s | -1.17% 0m00.84s | LegacyArithmetic/ZBounded | 0m00.80s || +0m00.03s | +4.99% 0m00.84s | Spec/EdDSA | 0m00.55s || +0m00.28s | +52.72% 0m00.83s | Compilers/Z/Bounds/MapCastByDeBruijn | 0m00.87s || -0m00.04s | -4.59% 0m00.83s | LegacyArithmetic/BaseSystem | 0m00.78s || +0m00.04s | +6.41% 0m00.82s | Compilers/Z/MapCastByDeBruijnWf | 0m00.89s || -0m00.07s | -7.86% 0m00.82s | LegacyArithmetic/Double/Proofs/ShiftLeftRightTactic | 0m00.82s || +0m00.00s | +0.00% 0m00.82s | Specific/Framework/MontgomeryReificationTypesPackage | 0m00.92s || -0m00.10s | -10.86% 0m00.81s | Compilers/Z/CommonSubexpressionEliminationInterp | 0m00.80s || +0m00.01s | +1.25% 0m00.80s | Compilers/Z/FoldTypes | 0m00.76s || +0m00.04s | +5.26% 0m00.80s | Compilers/Z/MapCastByDeBruijn | 0m00.77s || +0m00.03s | +3.89% N/A | Coqprime/PrimalityTest/Root | 0m00.80s || -0m00.80s | -100.00% 0m00.79s | Arithmetic/MontgomeryReduction/Definition | 0m00.71s || +0m00.08s | +11.26% 0m00.79s | Compilers/GeneralizeVarInterp | 0m00.75s || +0m00.04s | +5.33% 0m00.79s | Compilers/MapCastByDeBruijnWf | 0m01.12s || -0m00.33s | -29.46% 0m00.79s | Compilers/Z/CommonSubexpressionEliminationWf | 0m00.79s || +0m00.00s | +0.00% 0m00.79s | Experiments/NewPipeline/CompilersTestCases | 0m01.62s || -0m00.83s | -51.23% 0m00.79s | Specific/Framework/ArithmeticSynthesis/MontgomeryPackage | 0m00.78s || +0m00.01s | +1.28% 0m00.78s | Compilers/Z/InlineConstAndOpInterp | 0m00.72s || +0m00.06s | +8.33% 0m00.78s | Compilers/Z/InlineConstAndOpWf | 0m00.80s || -0m00.02s | -2.50% 0m00.78s | Util/ZBounded | 0m00.81s || -0m00.03s | -3.70% 0m00.77s | Compilers/GeneralizeVarWf | 0m00.76s || +0m00.01s | +1.31% 0m00.77s | Compilers/Z/RewriteAddToAdc | 0m00.78s || -0m00.01s | -1.28% 0m00.77s | Util/NUtil | 0m00.84s || -0m00.06s | -8.33% 0m00.76s | Algebra/SubsetoidRing | 0m00.94s || -0m00.17s | -19.14% 0m00.76s | Compilers/Z/InlineConstAndOpByRewriteInterp | 0m00.75s || +0m00.01s | +1.33% N/A | Coqprime/PrimalityTest/Cyclic | 0m00.76s || -0m00.76s | -100.00% 0m00.76s | Util/HList | 0m00.80s || -0m00.04s | -5.00% 0m00.75s | Compilers/Z/Bounds/Interpretation | 0m00.70s || +0m00.05s | +7.14% 0m00.75s | Compilers/Z/InlineConstAndOpByRewriteWf | 0m00.73s || +0m00.02s | +2.73% 0m00.75s | Compilers/Z/InlineWf | 0m00.82s || -0m00.06s | -8.53% 0m00.75s | Compilers/Z/InterpSideConditions | 0m00.55s || +0m00.19s | +36.36% 0m00.75s | Compilers/ZExtended/MapBaseType | 0m00.68s || +0m00.06s | +10.29% 0m00.75s | Util/Loops | 0m00.90s || -0m00.15s | -16.66% 0m00.74s | Compilers/Named/DeadCodeEliminationInterp | 0m00.70s || +0m00.04s | +5.71% 0m00.74s | Compilers/Named/PositiveContext/DefaultsProperties | 0m00.74s || +0m00.00s | +0.00% 0m00.74s | LegacyArithmetic/Interface | 0m01.04s || -0m00.30s | -28.84% 0m00.73s | Compilers/Z/GeneralizeVarInterp | 0m00.70s || +0m00.03s | +4.28% 0m00.73s | Spec/CompleteEdwardsCurve | 0m00.90s || -0m00.17s | -18.88% 0m00.72s | Algebra/Nsatz | 0m00.75s || -0m00.03s | -4.00% 0m00.72s | Compilers/InterpRewriting | 0m00.66s || +0m00.05s | +9.09% 0m00.72s | Specific/Framework/IntegrationTestDisplayCommonTactics | 0m00.70s || +0m00.02s | +2.85% 0m00.71s | Compilers/InterpProofs | 0m00.71s || +0m00.00s | +0.00% 0m00.71s | Compilers/Z/InlineConstAndOp | 0m00.51s || +0m00.19s | +39.21% 0m00.71s | Compilers/Z/Named/RewriteAddToAdc | 0m00.98s || -0m00.27s | -27.55% 0m00.71s | Compilers/ZExtended/Syntax | 0m00.54s || +0m00.16s | +31.48% 0m00.71s | Specific/X25519/C64/CurveParameters | 0m00.50s || +0m00.20s | +41.99% 0m00.70s | Compilers/InterpWf | 0m00.72s || -0m00.02s | -2.77% 0m00.70s | LegacyArithmetic/ArchitectureToZLike | 0m00.84s || -0m00.14s | -16.66% 0m00.70s | Util/ZRange | 0m00.70s || +0m00.00s | +0.00% 0m00.69s | Compilers/InputSyntax | 0m00.74s || -0m00.05s | -6.75% 0m00.69s | Compilers/Z/InlineConstAndOpByRewrite | 0m00.86s || -0m00.17s | -19.76% 0m00.69s | Spec/ModularArithmetic | 0m00.66s || +0m00.02s | +4.54% 0m00.68s | Compilers/CommonSubexpressionEliminationInterp | 0m00.98s || -0m00.29s | -30.61% 0m00.68s | Compilers/InterpWfRel | 0m00.78s || -0m00.09s | -12.82% 0m00.68s | Util/ZUtil/CPS | 0m00.61s || +0m00.07s | +11.47% 0m00.67s | Compilers/Z/Syntax | 0m00.66s || +0m00.01s | +1.51% 0m00.67s | Experiments/NewPipeline/AbstractInterpretationProofs | 0m00.60s || +0m00.07s | +11.66% 0m00.66s | Compilers/Reify | 0m00.60s || +0m00.06s | +10.00% 0m00.66s | Specific/Framework/CurveParameters | 0m00.64s || +0m00.02s | +3.12% 0m00.66s | Util/ZRange/Operations | 0m00.64s || +0m00.02s | +3.12% 0m00.64s | Experiments/PartialEvaluationWithLetIn | 0m00.61s || +0m00.03s | +4.91% 0m00.62s | Algebra/Monoid | 0m00.57s || +0m00.05s | +8.77% 0m00.62s | Compilers/InlineConstAndOp | 0m00.61s || +0m00.01s | +1.63% 0m00.62s | Compilers/InlineConstAndOpByRewriteWf | 0m00.78s || -0m00.16s | -20.51% 0m00.62s | Compilers/Named/WeakListContext | 0m00.62s || +0m00.00s | +0.00% 0m00.62s | Compilers/WfReflectiveGen | 0m00.60s || +0m00.02s | +3.33% 0m00.62s | Compilers/Z/GeneralizeVarWf | 0m00.75s || -0m00.13s | -17.33% 0m00.62s | Specific/Framework/RawCurveParameters | 0m00.58s || +0m00.04s | +6.89% 0m00.61s | Compilers/CommonSubexpressionEliminationDenote | 0m00.41s || +0m00.20s | +48.78% 0m00.61s | Compilers/Named/RegisterAssign | 0m00.60s || +0m00.01s | +1.66% 0m00.61s | Compilers/Z/Inline | 0m00.56s || +0m00.04s | +8.92% 0m00.61s | Util/BoundedWord | 0m00.57s || +0m00.04s | +7.01% 0m00.60s | Compilers/InlineConstAndOpByRewriteInterp | 0m00.68s || -0m00.08s | -11.76% 0m00.60s | Compilers/MapCastByDeBruijn | 0m00.61s || -0m00.01s | -1.63% 0m00.60s | LegacyArithmetic/Pow2Base | 0m00.73s || -0m00.13s | -17.80% 0m00.59s | Compilers/Z/Named/DeadCodeElimination | 0m00.51s || +0m00.07s | +15.68% 0m00.58s | Compilers/Linearize | 0m00.56s || +0m00.01s | +3.57% 0m00.58s | Compilers/Named/MapCast | 0m00.56s || +0m00.01s | +3.57% 0m00.58s | Compilers/Z/Bounds/Pipeline/OutputType | 0m00.61s || -0m00.03s | -4.91% 0m00.58s | Compilers/ZExtended/InlineConstAndOpWf | 0m00.53s || +0m00.04s | +9.43% 0m00.58s | Util/FixedWordSizes | 0m00.53s || +0m00.04s | +9.43% 0m00.58s | Util/ZUtil/Tactics/SimplifyFractionsLe | 0m00.43s || +0m00.14s | +34.88% 0m00.57s | Compilers/GeneralizeVar | 0m00.56s || +0m00.00s | +1.78% 0m00.57s | Compilers/Z/Named/DeadCodeEliminationInterp | 0m00.69s || -0m00.12s | -17.39% N/A | Coqprime/PrimalityTest/Zp | 0m00.57s || -0m00.56s | -100.00% 0m00.57s | Util/ZUtil/MulSplit | 0m00.48s || +0m00.08s | +18.74% 0m00.56s | Compilers/Z/OpInversion | 0m00.56s || +0m00.00s | +0.00% 0m00.56s | Compilers/Z/TypeInversion | 0m00.39s || +0m00.17s | +43.58% 0m00.56s | Specific/NISTP256/AMD64/CurveParameters | 0m00.61s || -0m00.04s | -8.19% 0m00.56s | Util/Decidable/Decidable2Bool | 0m00.81s || -0m00.25s | -30.86% 0m00.55s | Compilers/FilterLive | 0m00.47s || +0m00.08s | +17.02% 0m00.55s | Compilers/Named/IdContext | 0m00.50s || +0m00.05s | +10.00% 0m00.55s | Compilers/ZExtended/InlineConstAndOpByRewrite | 0m00.50s || +0m00.05s | +10.00% 0m00.55s | Compilers/ZExtended/InlineConstAndOpByRewriteWf | 0m00.45s || +0m00.10s | +22.22% 0m00.55s | Compilers/ZExtended/Syntax/Util | 0m00.58s || -0m00.02s | -5.17% 0m00.55s | Specific/X2448/Karatsuba/C64/CurveParameters | 0m00.38s || +0m00.17s | +44.73% 0m00.54s | Compilers/Inline | 0m00.54s || +0m00.00s | +0.00% 0m00.54s | Compilers/Named/InterpSideConditions | 0m00.40s || +0m00.14s | +35.00% 0m00.54s | Compilers/Named/Wf | 0m00.49s || +0m00.05s | +10.20% 0m00.53s | Compilers/Named/ContextDefinitions | 0m00.55s || -0m00.02s | -3.63% 0m00.53s | Compilers/ZExtended/InlineConstAndOpByRewriteInterp | 0m00.51s || +0m00.02s | +3.92% 0m00.53s | Compilers/ZExtended/InlineConstAndOpInterp | 0m00.58s || -0m00.04s | -8.62% 0m00.53s | Specific/Framework/CurveParametersPackage | 0m00.44s || +0m00.09s | +20.45% 0m00.53s | Util/ZRange/Show | 0m00.56s || -0m00.03s | -5.35% 0m00.53s | Util/ZUtil/Tactics/ZeroBounds | 0m00.40s || +0m00.13s | +32.50% 0m00.52s | Compilers/Named/Context | 0m00.47s || +0m00.05s | +10.63% 0m00.52s | Compilers/Named/CountLets | 0m00.44s || +0m00.08s | +18.18% 0m00.52s | Compilers/Named/GetNames | 0m00.50s || +0m00.02s | +4.00% 0m00.52s | Compilers/Named/InterpretToPHOAS | 0m00.55s || -0m00.03s | -5.45% 0m00.52s | Compilers/Tuple | 0m00.53s || -0m00.01s | -1.88% 0m00.52s | Util/ZUtil/Sgn | 0m00.51s || +0m00.01s | +1.96% 0m00.52s | Util/ZUtil/Tactics/PullPush/Modulo | 0m00.48s || +0m00.04s | +8.33% 0m00.51s | Compilers/CountLets | 0m00.42s || +0m00.09s | +21.42% 0m00.51s | Compilers/Named/ContextOn | 0m00.49s || +0m00.02s | +4.08% 0m00.51s | Util/AdditionChainExponentiation | 0m00.62s || -0m00.10s | -17.74% 0m00.51s | Util/Strings/String | 0m00.58s || -0m00.06s | -12.06% 0m00.51s | Util/ZUtil/Tactics/Ztestbit | 0m00.43s || +0m00.08s | +18.60% 0m00.50s | Compilers/ExprInversion | 0m00.46s || +0m00.03s | +8.69% 0m00.50s | Compilers/FoldTypes | 0m00.51s || -0m00.01s | -1.96% 0m00.50s | Compilers/InlineConstAndOpByRewrite | 0m00.50s || +0m00.00s | +0.00% 0m00.50s | Compilers/Z/InlineInterp | 0m00.59s || -0m00.08s | -15.25% N/A | Coqprime/List/UList | 0m00.50s || -0m00.50s | -100.00% 0m00.49s | Util/ZUtil/Hints/PullPush | 0m00.41s || +0m00.08s | +19.51% 0m00.48s | Compilers/Named/ContextProperties/Tactics | 0m00.53s || -0m00.05s | -9.43% 0m00.48s | Compilers/Z/GeneralizeVar | 0m00.49s || -0m00.01s | -2.04% 0m00.48s | Compilers/ZExtended/InlineConstAndOp | 0m00.52s || -0m00.04s | -7.69% 0m00.48s | Util/ZUtil/Hints/Ztestbit | 0m00.50s || -0m00.02s | -4.00% 0m00.48s | Util/ZUtil/ZSimplify/Core | 0m00.44s || +0m00.03s | +9.09% 0m00.48s | Util/ZUtil/Zselect | 0m00.44s || +0m00.03s | +9.09% 0m00.47s | Compilers/InterpByIso | 0m00.47s || +0m00.00s | +0.00% 0m00.47s | Util/IdfunWithAlt | 0m00.59s || -0m00.12s | -20.33% 0m00.47s | Util/ZUtil/Hints/ZArith | 0m00.49s || -0m00.02s | -4.08% 0m00.46s | Compilers/Named/DeadCodeElimination | 0m00.58s || -0m00.11s | -20.68% N/A | Coqprime/List/Permutation | 0m00.46s || -0m00.46s | -100.00% 0m00.46s | Experiments/NewPipeline/UnderLets | 0m00.72s || -0m00.25s | -36.11% 0m00.46s | Util/Sum | 0m00.44s || +0m00.02s | +4.54% 0m00.45s | Compilers/Named/SmartMap | 0m00.54s || -0m00.09s | -16.66% 0m00.45s | Util/ZUtil/Z2Nat | 0m00.41s || +0m00.04s | +9.75% 0m00.44s | Compilers/MapBaseType | 0m00.46s || -0m00.02s | -4.34% 0m00.44s | Util/Strings/HexString | 0m00.44s || +0m00.00s | +0.00% 0m00.44s | Util/ZUtil/Div/Bootstrap | 0m00.50s || -0m00.06s | -12.00% 0m00.44s | Util/ZUtil/Hints/Core | 0m00.52s || -0m00.08s | -15.38% 0m00.43s | Compilers/Named/EstablishLiveness | 0m00.38s || +0m00.04s | +13.15% 0m00.43s | Compilers/Named/ExprInversion | 0m00.56s || -0m00.13s | -23.21% 0m00.43s | Compilers/StripExpr | 0m00.50s || -0m00.07s | -14.00% 0m00.43s | Util/ZUtil/Tactics/LtbToLt | 0m00.54s || -0m00.11s | -20.37% 0m00.42s | Arithmetic/MontgomeryReduction/WordByWord/Abstract/Dependent/Definition | 0m00.43s || -0m00.01s | -2.32% 0m00.42s | Util/ZUtil/Hints | 0m00.40s || +0m00.01s | +4.99% 0m00.42s | Util/ZUtil/Le | 0m00.43s || -0m00.01s | -2.32% 0m00.42s | Util/ZUtil/ZSimplify | 0m00.28s || +0m00.13s | +49.99% 0m00.42s | bbv/Nomega | 0m00.45s || -0m00.03s | -6.66% 0m00.41s | Util/ZUtil/Sorting | 0m00.47s || -0m00.06s | -12.76% 0m00.41s | Util/ZUtil/Tactics/PrimeBound | 0m00.36s || +0m00.04s | +13.88% 0m00.41s | bbv/HexNotationWord | 0m00.45s || -0m00.04s | -8.88% 0m00.40s | Compilers/Named/PositiveContext | 0m00.59s || -0m00.18s | -32.20% 0m00.40s | Compilers/Named/Syntax | 0m00.50s || -0m00.09s | -19.99% N/A | Coqprime/List/ListAux | 0m00.40s || -0m00.40s | -100.00% 0m00.40s | Util/SideConditions/RingPackage | 0m00.37s || +0m00.03s | +8.10% 0m00.40s | Util/ZUtil/Tactics/DivModToQuotRem | 0m00.38s || +0m00.02s | +5.26% 0m00.40s | Util/ZUtil/Tactics/LinearSubstitute | 0m00.42s || -0m00.01s | -4.76% 0m00.39s | Compilers/Equality | 0m00.38s || +0m00.01s | +2.63% 0m00.39s | Util/SideConditions/Autosolve | 0m00.28s || +0m00.10s | +39.28% 0m00.39s | Util/SideConditions/ModInvPackage | 0m00.41s || -0m00.01s | -4.87% 0m00.39s | bbv/HexNotation | 0m00.38s || +0m00.01s | +2.63% N/A | Coqprime/PrimalityTest/Lagrange | 0m00.38s || -0m00.38s | -100.00% 0m00.38s | Specific/NISTP256/AMD128/CurveParameters | 0m00.58s || -0m00.19s | -34.48% 0m00.38s | Util/ZUtil/AddModulo | 0m00.28s || +0m00.09s | +35.71% 0m00.38s | Util/ZUtil/Modulo/Bootstrap | 0m00.40s || -0m00.02s | -5.00% 0m00.38s | Util/ZUtil/Tactics/CompareToSgn | 0m00.43s || -0m00.04s | -11.62% 0m00.38s | Util/ZUtil/Tactics/DivideExistsMul | 0m00.38s || +0m00.00s | +0.00% 0m00.38s | bbv/WordScope | 0m00.40s || -0m00.02s | -5.00% 0m00.37s | Algebra/Hierarchy | 0m00.40s || -0m00.03s | -7.50% 0m00.37s | Compilers/Named/Compile | 0m00.50s || -0m00.13s | -26.00% N/A | Coqprime/List/ZProgression | 0m00.37s || -0m00.37s | -100.00% N/A | Coqprime/PrimalityTest/IGroup | 0m00.37s || -0m00.37s | -100.00% 0m00.37s | Util/ZUtil/Ge | 0m00.33s || +0m00.03s | +12.12% 0m00.37s | Util/ZUtil/Land | 0m00.43s || -0m00.06s | -13.95% 0m00.36s | Arithmetic/MontgomeryReduction/WordByWord/Abstract/Definition | 0m00.42s || -0m00.06s | -14.28% 0m00.36s | Compilers/Named/MapType | 0m00.33s || +0m00.02s | +9.09% 0m00.36s | Compilers/Named/PositiveContext/Defaults | 0m00.57s || -0m00.20s | -36.84% 0m00.36s | Util/Strings/OctalString | 0m00.33s || +0m00.02s | +9.09% 0m00.36s | Util/ZUtil/Definitions | 0m00.40s || -0m00.04s | -10.00% 0m00.36s | Util/ZUtil/Tactics/PullPush | 0m00.39s || -0m00.03s | -7.69% 0m00.36s | Util/ZUtil/Tactics/ReplaceNegWithPos | 0m00.33s || +0m00.02s | +9.09% 0m00.36s | bbv/BinNotation | 0m00.37s || -0m00.01s | -2.70% N/A | Coqprime/PrimalityTest/Euler | 0m00.35s || -0m00.35s | -100.00% 0m00.35s | Spec/MxDH | 0m00.39s || -0m00.04s | -10.25% 0m00.35s | Util/Decidable/Bool2Prop | 0m00.22s || +0m00.12s | +59.09% 0m00.35s | Util/ZUtil/Tactics | 0m00.48s || -0m00.13s | -27.08% 0m00.35s | Util/ZUtil/Tactics/PeelLe | 0m00.44s || -0m00.09s | -20.45% 0m00.35s | Util/ZUtil/Tactics/SplitMinMax | 0m00.35s || +0m00.00s | +0.00% 0m00.34s | Util/Option | 0m00.31s || +0m00.03s | +9.67% 0m00.34s | Util/ZUtil/ModInv | 0m00.38s || -0m00.03s | -10.52% 0m00.34s | bbv/BinNotationZ | 0m00.34s || +0m00.00s | +0.00% 0m00.34s | bbv/HexNotationZ | 0m00.37s || -0m00.02s | -8.10% 0m00.34s | bbv/NLib | 0m00.42s || -0m00.07s | -19.04% 0m00.33s | Util/Strings/Show | 0m00.45s || -0m00.12s | -26.66% N/A | Coqprime/List/Iterator | 0m00.31s || -0m00.31s | -100.00% 0m00.31s | Util/PointedProp | 0m00.30s || +0m00.01s | +3.33% 0m00.29s | Util/LetInMonad | 0m00.29s || +0m00.00s | +0.00% 0m00.28s | Compilers/EtaInterp | 0m00.34s || -0m00.06s | -17.64% 0m00.28s | Compilers/InSet/TypeifyInterp | 0m00.18s || +0m00.10s | +55.55% 0m00.28s | Util/Strings/BinaryString | 0m00.32s || -0m00.03s | -12.49% 0m00.28s | Util/Strings/Equality | 0m00.29s || -0m00.00s | -3.44% N/A | Coqprime/PrimalityTest/FGroup | 0m00.27s || -0m00.27s | -100.00% 0m00.27s | Util/Strings/Ascii | 0m00.33s || -0m00.06s | -18.18% 0m00.27s | Util/Strings/Decimal | 0m00.26s || +0m00.01s | +3.84% N/A | Coqprime/N/NatAux | 0m00.26s || -0m00.26s | -100.00% 0m00.26s | Util/ParseTaps | 0m00.29s || -0m00.02s | -10.34% 0m00.25s | Util/SideConditions/ReductionPackages | 0m00.24s || +0m00.01s | +4.16% 0m00.24s | Util/ZUtil/Notations | 0m00.29s || -0m00.04s | -17.24% 0m00.20s | Compilers/Conversion | 0m00.12s || +0m00.08s | +66.66% 0m00.20s | Util/ListUtil/FoldBool | 0m00.20s || +0m00.00s | +0.00% 0m00.19s | Compilers/Named/NameUtil | 0m00.18s || +0m00.01s | +5.55% 0m00.19s | Compilers/Wf | 0m00.20s || -0m00.01s | -5.00% 0m00.18s | Specific/Framework/Packages | 0m00.17s || +0m00.00s | +5.88% 0m00.18s | Util/PrimitiveProd | 0m00.19s || -0m00.01s | -5.26% 0m00.18s | Util/Relations | 0m00.14s || +0m00.03s | +28.57% 0m00.18s | bbv/DepEq | 0m00.22s || -0m00.04s | -18.18% 0m00.17s | Util/ListUtil/Forall | 0m00.18s || -0m00.00s | -5.55% 0m00.17s | Util/Sigma | 0m00.14s || +0m00.03s | +21.42% 0m00.16s | Compilers/RewriterWf | 0m00.16s || +0m00.00s | +0.00% 0m00.16s | Util/TagList | 0m00.20s || -0m00.04s | -20.00% 0m00.14s | Compilers/RewriterInterp | 0m00.12s || +0m00.02s | +16.66% 0m00.14s | Compilers/TypeInversion | 0m00.14s || +0m00.00s | +0.00% 0m00.12s | Compilers/InSet/Syntax | 0m00.09s || +0m00.03s | +33.33% 0m00.12s | Compilers/InterpSideConditions | 0m00.07s || +0m00.04s | +71.42% 0m00.12s | Util/AutoRewrite | 0m00.09s || +0m00.03s | +33.33% 0m00.12s | Util/Equality | 0m00.13s || -0m00.01s | -7.69% 0m00.12s | Util/PrimitiveHList | 0m00.14s || -0m00.02s | -14.28% 0m00.12s | Util/Prod | 0m00.18s || -0m00.06s | -33.33% 0m00.11s | Compilers/RenameBinders | 0m00.10s || +0m00.00s | +9.99% 0m00.11s | Compilers/Rewriter | 0m00.10s || +0m00.00s | +9.99% 0m00.11s | Compilers/TypeUtil | 0m00.08s || +0m00.03s | +37.50% 0m00.11s | Util/HProp | 0m00.10s || +0m00.00s | +9.99% 0m00.11s | Util/IffT | 0m00.05s || +0m00.06s | +120.00% 0m00.11s | Util/Tactics | 0m00.08s || +0m00.03s | +37.50% 0m00.10s | Compilers/Eta | 0m00.11s || -0m00.00s | -9.09% 0m00.10s | Compilers/Syntax | 0m00.13s || -0m00.03s | -23.07% 0m00.10s | Util/Bool | 0m00.08s || +0m00.02s | +25.00% 0m00.10s | Util/Isomorphism | 0m00.12s || -0m00.01s | -16.66% 0m00.10s | Util/LetIn | 0m00.09s || +0m00.01s | +11.11% 0m00.10s | Util/Sumbool | 0m00.09s || +0m00.01s | +11.11% 0m00.10s | Util/Tactics/MoveLetIn | 0m00.09s || +0m00.01s | +11.11% 0m00.10s | Util/Tactics/Revert | 0m00.07s || +0m00.03s | +42.85% 0m00.10s | Util/Tower | 0m00.10s || +0m00.00s | +0.00% 0m00.10s | bbv/DepEqNat | 0m00.06s || +0m00.04s | +66.66% 0m00.09s | Compilers/InSet/Typeify | 0m00.12s || -0m00.03s | -25.00% 0m00.09s | Util/Tactics/Contains | 0m00.04s || +0m00.05s | +124.99% 0m00.09s | Util/Tactics/ConvoyDestruct | 0m00.05s || +0m00.03s | +79.99% 0m00.09s | Util/Tactics/DestructHead | 0m00.10s || -0m00.01s | -10.00% 0m00.09s | Util/Tactics/ETransitivity | 0m00.08s || +0m00.00s | +12.49% 0m00.09s | Util/Tactics/SpecializeBy | 0m00.06s || +0m00.03s | +50.00% 0m00.08s | Compilers/Intros | 0m00.08s || +0m00.00s | +0.00% 0m00.08s | Compilers/Map | 0m00.10s || -0m00.02s | -20.00% 0m00.08s | Util/Bool/IsTrue | 0m00.06s || +0m00.02s | +33.33% 0m00.08s | Util/ErrorT | 0m00.07s || +0m00.00s | +14.28% 0m00.08s | Util/Logic | 0m00.08s || +0m00.00s | +0.00% 0m00.08s | Util/Pointed | 0m00.08s || +0m00.00s | +0.00% 0m00.08s | Util/Pos | 0m00.04s || +0m00.04s | +100.00% 0m00.08s | Util/SideConditions/AdmitPackage | 0m00.08s || +0m00.00s | +0.00% 0m00.08s | Util/Sigma/Lift | 0m00.06s || +0m00.02s | +33.33% 0m00.08s | Util/Tactics/CacheTerm | 0m00.08s || +0m00.00s | +0.00% 0m00.08s | Util/Tactics/DebugPrint | 0m00.10s || -0m00.02s | -20.00% 0m00.08s | Util/Tactics/DestructTrivial | 0m00.05s || +0m00.03s | +60.00% 0m00.08s | Util/Tactics/GetGoal | 0m00.06s || +0m00.02s | +33.33% 0m00.08s | Util/Tactics/Head | 0m00.07s || +0m00.00s | +14.28% 0m00.08s | Util/Tactics/RewriteHyp | 0m00.06s || +0m00.02s | +33.33% 0m00.08s | Util/Tactics/SubstEvars | 0m00.07s || +0m00.00s | +14.28% 0m00.08s | Util/Tactics/UnifyAbstractReflexivity | 0m00.06s || +0m00.02s | +33.33% 0m00.08s | Util/Tactics/VM | 0m00.08s || +0m00.00s | +0.00% 0m00.07s | LegacyArithmetic/VerdiTactics | 0m00.10s || -0m00.03s | -30.00% 0m00.07s | Util/Bool/Equality | 0m00.07s || +0m00.00s | +0.00% 0m00.07s | Util/CPSNotations | 0m00.09s || -0m00.01s | -22.22% 0m00.07s | Util/Logic/ImplAnd | 0m00.07s || +0m00.00s | +0.00% 0m00.07s | Util/Tactics/BreakMatch | 0m00.06s || +0m00.01s | +16.66% 0m00.07s | Util/Tactics/DestructHyps | 0m00.07s || +0m00.00s | +0.00% 0m00.07s | Util/Tactics/DoWithHyp | 0m00.09s || -0m00.01s | -22.22% 0m00.07s | Util/Tactics/ESpecialize | 0m00.08s || -0m00.00s | -12.49% 0m00.07s | Util/Tactics/HeadUnderBinders | 0m00.06s || +0m00.01s | +16.66% 0m00.07s | Util/Tactics/Not | 0m00.07s || +0m00.00s | +0.00% 0m00.07s | Util/Tactics/PoseTermWithName | 0m00.06s || +0m00.01s | +16.66% 0m00.07s | Util/Tactics/PrintContext | 0m00.06s || +0m00.01s | +16.66% 0m00.07s | Util/Tactics/SetEvars | 0m00.05s || +0m00.02s | +40.00% 0m00.07s | Util/Tactics/SpecializeAllWays | 0m00.08s || -0m00.00s | -12.49% 0m00.07s | Util/Tactics/SplitInContext | 0m00.07s || +0m00.00s | +0.00% 0m00.07s | Util/Tactics/TransparentAssert | 0m00.06s || +0m00.01s | +16.66% 0m00.07s | Util/Unit | 0m00.06s || +0m00.01s | +16.66% 0m00.06s | Util/Curry | 0m00.08s || -0m00.02s | -25.00% 0m00.06s | Util/DefaultedTypes | 0m00.07s || -0m00.01s | -14.28% 0m00.06s | Util/FixCoqMistakes | 0m00.09s || -0m00.03s | -33.33% 0m00.06s | Util/GlobalSettings | 0m00.12s || -0m00.06s | -50.00% 0m00.06s | Util/SideConditions/CorePackages | 0m00.07s || -0m00.01s | -14.28% 0m00.06s | Util/Sigma/Associativity | 0m00.08s || -0m00.02s | -25.00% 0m00.06s | Util/Sigma/MapProjections | 0m00.05s || +0m00.00s | +19.99% 0m00.06s | Util/Tactics/ClearDuplicates | 0m00.07s || -0m00.01s | -14.28% 0m00.06s | Util/Tactics/ClearbodyAll | 0m00.07s || -0m00.01s | -14.28% 0m00.06s | Util/Tactics/EvarExists | 0m00.06s || +0m00.00s | +0.00% 0m00.06s | Util/Tactics/Forward | 0m00.04s || +0m00.01s | +49.99% 0m00.06s | Util/Tactics/OnSubterms | 0m00.04s || +0m00.01s | +49.99% 0m00.06s | Util/Tactics/RunTacticAsConstr | 0m00.06s || +0m00.00s | +0.00% 0m00.06s | Util/Tactics/SideConditionsBeforeToAfter | 0m00.06s || +0m00.00s | +0.00% 0m00.06s | Util/Tactics/SimplifyProjections | 0m00.08s || -0m00.02s | -25.00% 0m00.06s | Util/Tactics/SubstLet | 0m00.06s || +0m00.00s | +0.00% 0m00.06s | Util/Tactics/Test | 0m00.07s || -0m00.01s | -14.28% 0m00.05s | Util/ChangeInAll | 0m00.06s || -0m00.00s | -16.66% 0m00.05s | Util/Notations | 0m00.08s || -0m00.03s | -37.50% 0m00.05s | Util/Tactics/SimplifyRepeatedIfs | 0m00.06s || -0m00.00s | -16.66% 0m00.05s | Util/Tactics/UnfoldArg | 0m00.08s || -0m00.03s | -37.50% 0m00.05s | Util/Tactics/UniquePose | 0m00.06s || -0m00.00s | -16.66% 0m00.04s | Util/OptionList | 0m00.09s || -0m00.05s | -55.55% 0m00.04s | Util/Tactics/ChangeInAll | 0m00.08s || -0m00.04s | -50.00% 0m00.04s | Util/Tactics/SetoidSubst | 0m00.05s || -0m00.01s | -20.00% 0m00.03s | Util/Tactics/ClearAll | 0m00.06s || -0m00.03s | -50.00% N/A | Coqprime/Tactic/Tactic | 0m00.02s || -0m00.02s | -100.00% --- .gitignore | 2 + Makefile | 13 +- _CoqProject | 2 + curve25519_32.c | 4 +- curve25519_64.c | 2 +- p256_32.c | 3398 ++ p256_64.c | 1344 + src/Experiments/NewPipeline/Arithmetic.v | 1327 +- src/Experiments/NewPipeline/CLI.v | 101 + src/Experiments/NewPipeline/CStringification.v | 56 +- src/Experiments/NewPipeline/CompilersTestCases.v | 8 +- .../ExtractionHaskell/word_by_word_montgomery.v | 4 + .../ExtractionOCaml/word_by_word_montgomery.v | 3 + src/Experiments/NewPipeline/Language.v | 75 +- src/Experiments/NewPipeline/Rewriter.v | 463 +- .../NewPipeline/StandaloneHaskellMain.v | 12 + src/Experiments/NewPipeline/StandaloneOCamlMain.v | 9 + src/Experiments/NewPipeline/Toplevel1.v | 985 +- src/Experiments/NewPipeline/arith_rewrite_head.out | 16842 ++++++++ src/Experiments/NewPipeline/fancy_rewrite_head.out | 39449 ++++++++++++++++--- src/Experiments/NewPipeline/nbe_rewrite_head.out | 5123 +++ src/Experiments/NewPipeline/rewrite_head.out | 17274 -------- 22 files changed, 63747 insertions(+), 22749 deletions(-) create mode 100644 p256_32.c create mode 100644 p256_64.c create mode 100644 src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.v create mode 100644 src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.v create mode 100644 src/Experiments/NewPipeline/arith_rewrite_head.out create mode 100644 src/Experiments/NewPipeline/nbe_rewrite_head.out delete mode 100644 src/Experiments/NewPipeline/rewrite_head.out diff --git a/.gitignore b/.gitignore index bcf8f7b6f..28e5da044 100644 --- a/.gitignore +++ b/.gitignore @@ -106,11 +106,13 @@ third_party/openssl-nistz256/measure third_party/curve25519-donna-c64/measure src/Experiments/NewPipeline/ExtractionHaskell/saturated_solinas src/Experiments/NewPipeline/ExtractionHaskell/unsaturated_solinas +src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery src/Experiments/NewPipeline/ExtractionHaskell/*.hi src/Experiments/NewPipeline/ExtractionHaskell/*.hs src/Experiments/NewPipeline/ExtractionHaskell/*.o src/Experiments/NewPipeline/ExtractionOCaml/saturated_solinas src/Experiments/NewPipeline/ExtractionOCaml/unsaturated_solinas +src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery src/Experiments/NewPipeline/ExtractionOCaml/*.cmi src/Experiments/NewPipeline/ExtractionOCaml/*.cmx src/Experiments/NewPipeline/ExtractionOCaml/*.ml diff --git a/Makefile b/Makefile index 06efe2ffd..695398714 100644 --- a/Makefile +++ b/Makefile @@ -476,7 +476,8 @@ build-selected-bench: $(SELECTED_MEASURE_BINARIES) STANDALONE := \ unsaturated_solinas \ - saturated_solinas + saturated_solinas \ + word_by_word_montgomery $(STANDALONE:%=src/Experiments/NewPipeline/ExtractionOCaml/%.ml) : %.ml : %.v src/Experiments/NewPipeline/StandaloneOCamlMain.vo $(SHOW)'COQC $< > $@' @@ -500,19 +501,27 @@ standalone-haskell: $(STANDALONE:%=src/Experiments/NewPipeline/ExtractionHaskell standalone-ocaml: $(STANDALONE:%=src/Experiments/NewPipeline/ExtractionOCaml/%) UNSATURATED_SOLINAS_C_FILES := curve25519_64.c curve25519_32.c +WORD_BY_WORD_MONTGOMERY_C_FILES := p256_64.c p256_32.c FUNCTIONS_FOR_25519 := carry_mul carry_square carry_scmul121666 carry add sub opp selectznz to_bytes from_bytes UNSATURATED_SOLINAS := src/Experiments/NewPipeline/ExtractionOCaml/unsaturated_solinas +WORD_BY_WORD_MONTGOMERY := src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery .PHONY: c-files -c-files: $(UNSATURATED_SOLINAS_C_FILES) +c-files: $(UNSATURATED_SOLINAS_C_FILES) $(WORD_BY_WORD_MONTGOMERY_C_FILES) $(UNSATURATED_SOLINAS_C_FILES): $(UNSATURATED_SOLINAS) +$(WORD_BY_WORD_MONTGOMERY_C_FILES): $(WORD_BY_WORD_MONTGOMERY) + curve25519_64.c: $(UNSATURATED_SOLINAS) '25519' '5' '2^255' '1,19' '64' $(FUNCTIONS_FOR_25519) > $@ curve25519_32.c: $(UNSATURATED_SOLINAS) '25519' '10' '2^255' '1,19' '32' $(FUNCTIONS_FOR_25519) > $@ +# 2^256 - 2^224 + 2^192 + 2^96 - 1 +p256_64.c p256_32.c : p256_%.c : + $(WORD_BY_WORD_MONTGOMERY) 'p256' '2^256' '2^224,1;2^192,-1;2^96,-1;1,1' '$*' > $@ + clean:: rm -f Makefile.coq remake_curves.log src/Specific/.autgenerated-deps diff --git a/_CoqProject b/_CoqProject index 9e426282f..cdccf354e 100644 --- a/_CoqProject +++ b/_CoqProject @@ -260,8 +260,10 @@ src/Experiments/NewPipeline/Toplevel2.v src/Experiments/NewPipeline/UnderLets.v src/Experiments/NewPipeline/ExtractionHaskell/saturated_solinas.v src/Experiments/NewPipeline/ExtractionHaskell/unsaturated_solinas.v +src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.v src/Experiments/NewPipeline/ExtractionOCaml/saturated_solinas.v src/Experiments/NewPipeline/ExtractionOCaml/unsaturated_solinas.v +src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.v src/LegacyArithmetic/ArchitectureToZLike.v src/LegacyArithmetic/ArchitectureToZLikeProofs.v src/LegacyArithmetic/BarretReduction.v diff --git a/curve25519_32.c b/curve25519_32.c index 56c29e6d3..5c3add9e9 100644 --- a/curve25519_32.c +++ b/curve25519_32.c @@ -39,7 +39,7 @@ static void fiat_25519_addcarryx_u26(uint32_t* out1, fiat_25519_uint1* out2, fia */ static void fiat_25519_subborrowx_u26(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { int32_t x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 26); + fiat_25519_int1 x2 = (fiat_25519_int1)((uint32_t)x1 >> 26); uint32_t x3 = (x1 & UINT32_C(0x3ffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); @@ -73,7 +73,7 @@ static void fiat_25519_addcarryx_u25(uint32_t* out1, fiat_25519_uint1* out2, fia */ static void fiat_25519_subborrowx_u25(uint32_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint32_t arg2, uint32_t arg3) { int32_t x1 = ((int32_t)(arg2 - arg1) - (int32_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 25); + fiat_25519_int1 x2 = (fiat_25519_int1)((uint32_t)x1 >> 25); uint32_t x3 = (x1 & UINT32_C(0x1ffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); diff --git a/curve25519_64.c b/curve25519_64.c index cb16fdecd..899f37e40 100644 --- a/curve25519_64.c +++ b/curve25519_64.c @@ -41,7 +41,7 @@ static void fiat_25519_addcarryx_u51(uint64_t* out1, fiat_25519_uint1* out2, fia */ static void fiat_25519_subborrowx_u51(uint64_t* out1, fiat_25519_uint1* out2, fiat_25519_uint1 arg1, uint64_t arg2, uint64_t arg3) { int64_t x1 = ((int64_t)(arg2 - (int64_t)arg1) - (int64_t)arg3); - fiat_25519_int1 x2 = (fiat_25519_int1)(x1 >> 51); + fiat_25519_int1 x2 = (fiat_25519_int1)((uint64_t)x1 >> 51); uint64_t x3 = (x1 & UINT64_C(0x7ffffffffffff)); *out1 = x3; *out2 = (fiat_25519_uint1)(0x0 - x2); diff --git a/p256_32.c b/p256_32.c new file mode 100644 index 000000000..5fc3d8679 --- /dev/null +++ b/p256_32.c @@ -0,0 +1,3398 @@ +/* Autogenerated */ +/* curve description: p256 */ +/* requested operations: (all) */ +/* s = 0x10000000000000000000000000000000000000000000000000000000000000000 (from "2^256") */ +/* c = [(26959946667150639794667015087019630673637144422540572481103610249216, 1), (6277101735386680763835789423207666416102355444464034512896, -1), (79228162514264337593543950336, -1), (1, 1)] (from "2^224,1;2^192,-1;2^96,-1;1,1") */ +/* machine_wordsize = 32 (from "32") */ + +#include +typedef unsigned char fiat_p256_uint1; +typedef signed char fiat_p256_int1; + + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0x1] + */ +static void fiat_p256_addcarryx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + uint64_t x1 = ((arg1 + (uint64_t)arg2) + arg3); + uint32_t x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + fiat_p256_uint1 x3 = (fiat_p256_uint1)(x1 >> 32); + *out1 = x2; + *out2 = x3; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0x1] + */ +static void fiat_p256_subborrowx_u32(uint32_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + int64_t x1 = ((arg2 - (int64_t)arg1) - arg3); + fiat_p256_int1 x2 = (fiat_p256_int1)((uint64_t)x1 >> 32); + uint32_t x3 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + *out1 = x3; + *out2 = (fiat_p256_uint1)(0x0 - x2); +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0xffffffff] + * arg2: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + * out2: [0x0 ~> 0xffffffff] + */ +static void fiat_p256_mulx_u32(uint32_t* out1, uint32_t* out2, uint32_t arg1, uint32_t arg2) { + uint64_t x1 = ((uint64_t)arg1 * arg2); + uint32_t x2 = (uint32_t)(x1 & UINT32_C(0xffffffff)); + uint32_t x3 = (uint32_t)(x1 >> 32); + *out1 = x2; + *out2 = x3; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffff] + * arg3: [0x0 ~> 0xffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + */ +static void fiat_p256_cmovznz_u32(uint32_t* out1, fiat_p256_uint1 arg1, uint32_t arg2, uint32_t arg3) { + fiat_p256_uint1 x1 = (!(!arg1)); + uint32_t x2 = ((fiat_p256_int1)(0x0 - x1) & UINT32_C(0xffffffff)); + uint32_t x3 = ((x2 & arg3) | (uint32_t)((uint64_t)(~x2) & arg2)); + *out1 = x3; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_mul(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { + uint32_t x1 = (arg1[1]); + uint32_t x2 = (arg1[2]); + uint32_t x3 = (arg1[3]); + uint32_t x4 = (arg1[4]); + uint32_t x5 = (arg1[5]); + uint32_t x6 = (arg1[6]); + uint32_t x7 = (arg1[7]); + uint32_t x8 = (arg1[0]); + uint32_t x9; + uint32_t x10; + fiat_p256_mulx_u32(&x9, &x10, x8, (arg2[7])); + uint32_t x11; + uint32_t x12; + fiat_p256_mulx_u32(&x11, &x12, x8, (arg2[6])); + uint32_t x13; + uint32_t x14; + fiat_p256_mulx_u32(&x13, &x14, x8, (arg2[5])); + uint32_t x15; + uint32_t x16; + fiat_p256_mulx_u32(&x15, &x16, x8, (arg2[4])); + uint32_t x17; + uint32_t x18; + fiat_p256_mulx_u32(&x17, &x18, x8, (arg2[3])); + uint32_t x19; + uint32_t x20; + fiat_p256_mulx_u32(&x19, &x20, x8, (arg2[2])); + uint32_t x21; + uint32_t x22; + fiat_p256_mulx_u32(&x21, &x22, x8, (arg2[1])); + uint32_t x23; + uint32_t x24; + fiat_p256_mulx_u32(&x23, &x24, x8, (arg2[0])); + uint32_t x25; + fiat_p256_uint1 x26; + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x21, x24); + uint32_t x27; + fiat_p256_uint1 x28; + fiat_p256_addcarryx_u32(&x27, &x28, x26, x19, x22); + uint32_t x29; + fiat_p256_uint1 x30; + fiat_p256_addcarryx_u32(&x29, &x30, x28, x17, x20); + uint32_t x31; + fiat_p256_uint1 x32; + fiat_p256_addcarryx_u32(&x31, &x32, x30, x15, x18); + uint32_t x33; + fiat_p256_uint1 x34; + fiat_p256_addcarryx_u32(&x33, &x34, x32, x13, x16); + uint32_t x35; + fiat_p256_uint1 x36; + fiat_p256_addcarryx_u32(&x35, &x36, x34, x11, x14); + uint32_t x37; + fiat_p256_uint1 x38; + fiat_p256_addcarryx_u32(&x37, &x38, x36, x9, x12); + uint32_t x39; + fiat_p256_uint1 x40; + fiat_p256_addcarryx_u32(&x39, &x40, x38, 0x0, x10); + uint32_t x41; + uint32_t x42; + fiat_p256_mulx_u32(&x41, &x42, x23, UINT32_C(0xffffffff)); + uint32_t x43; + uint32_t x44; + fiat_p256_mulx_u32(&x43, &x44, x23, UINT32_C(0xffffffff)); + uint32_t x45; + uint32_t x46; + fiat_p256_mulx_u32(&x45, &x46, x23, UINT32_C(0xffffffff)); + uint32_t x47; + uint32_t x48; + fiat_p256_mulx_u32(&x47, &x48, x23, UINT32_C(0xffffffff)); + uint32_t x49; + fiat_p256_uint1 x50; + fiat_p256_addcarryx_u32(&x49, &x50, 0x0, x45, x48); + uint32_t x51; + fiat_p256_uint1 x52; + fiat_p256_addcarryx_u32(&x51, &x52, x50, x43, x46); + uint32_t x53; + fiat_p256_uint1 x54; + fiat_p256_addcarryx_u32(&x53, &x54, x52, 0x0, x44); + uint32_t x55; + fiat_p256_uint1 x56; + fiat_p256_addcarryx_u32(&x55, &x56, x54, 0x0, 0x0); + uint32_t x57; + fiat_p256_uint1 x58; + fiat_p256_addcarryx_u32(&x57, &x58, 0x0, x47, x23); + uint32_t x59; + fiat_p256_uint1 x60; + fiat_p256_addcarryx_u32(&x59, &x60, x58, x49, x25); + uint32_t x61; + fiat_p256_uint1 x62; + fiat_p256_addcarryx_u32(&x61, &x62, x60, x51, x27); + uint32_t x63; + fiat_p256_uint1 x64; + fiat_p256_addcarryx_u32(&x63, &x64, x62, x53, x29); + uint32_t x65; + fiat_p256_uint1 x66; + fiat_p256_addcarryx_u32(&x65, &x66, x64, (fiat_p256_uint1)x55, x31); + uint32_t x67; + fiat_p256_uint1 x68; + fiat_p256_addcarryx_u32(&x67, &x68, x66, 0x0, x33); + uint32_t x69; + fiat_p256_uint1 x70; + fiat_p256_addcarryx_u32(&x69, &x70, x68, x23, x35); + uint32_t x71; + fiat_p256_uint1 x72; + fiat_p256_addcarryx_u32(&x71, &x72, x70, x41, x37); + uint32_t x73; + fiat_p256_uint1 x74; + fiat_p256_addcarryx_u32(&x73, &x74, x72, x42, x39); + uint32_t x75; + fiat_p256_uint1 x76; + fiat_p256_addcarryx_u32(&x75, &x76, x74, 0x0, 0x0); + uint32_t x77; + uint32_t x78; + fiat_p256_mulx_u32(&x77, &x78, x1, (arg2[7])); + uint32_t x79; + uint32_t x80; + fiat_p256_mulx_u32(&x79, &x80, x1, (arg2[6])); + uint32_t x81; + uint32_t x82; + fiat_p256_mulx_u32(&x81, &x82, x1, (arg2[5])); + uint32_t x83; + uint32_t x84; + fiat_p256_mulx_u32(&x83, &x84, x1, (arg2[4])); + uint32_t x85; + uint32_t x86; + fiat_p256_mulx_u32(&x85, &x86, x1, (arg2[3])); + uint32_t x87; + uint32_t x88; + fiat_p256_mulx_u32(&x87, &x88, x1, (arg2[2])); + uint32_t x89; + uint32_t x90; + fiat_p256_mulx_u32(&x89, &x90, x1, (arg2[1])); + uint32_t x91; + uint32_t x92; + fiat_p256_mulx_u32(&x91, &x92, x1, (arg2[0])); + uint32_t x93; + fiat_p256_uint1 x94; + fiat_p256_addcarryx_u32(&x93, &x94, 0x0, x89, x92); + uint32_t x95; + fiat_p256_uint1 x96; + fiat_p256_addcarryx_u32(&x95, &x96, x94, x87, x90); + uint32_t x97; + fiat_p256_uint1 x98; + fiat_p256_addcarryx_u32(&x97, &x98, x96, x85, x88); + uint32_t x99; + fiat_p256_uint1 x100; + fiat_p256_addcarryx_u32(&x99, &x100, x98, x83, x86); + uint32_t x101; + fiat_p256_uint1 x102; + fiat_p256_addcarryx_u32(&x101, &x102, x100, x81, x84); + uint32_t x103; + fiat_p256_uint1 x104; + fiat_p256_addcarryx_u32(&x103, &x104, x102, x79, x82); + uint32_t x105; + fiat_p256_uint1 x106; + fiat_p256_addcarryx_u32(&x105, &x106, x104, x77, x80); + uint32_t x107; + fiat_p256_uint1 x108; + fiat_p256_addcarryx_u32(&x107, &x108, x106, 0x0, x78); + uint32_t x109; + fiat_p256_uint1 x110; + fiat_p256_addcarryx_u32(&x109, &x110, 0x0, x91, x59); + uint32_t x111; + fiat_p256_uint1 x112; + fiat_p256_addcarryx_u32(&x111, &x112, x110, x93, x61); + uint32_t x113; + fiat_p256_uint1 x114; + fiat_p256_addcarryx_u32(&x113, &x114, x112, x95, x63); + uint32_t x115; + fiat_p256_uint1 x116; + fiat_p256_addcarryx_u32(&x115, &x116, x114, x97, x65); + uint32_t x117; + fiat_p256_uint1 x118; + fiat_p256_addcarryx_u32(&x117, &x118, x116, x99, x67); + uint32_t x119; + fiat_p256_uint1 x120; + fiat_p256_addcarryx_u32(&x119, &x120, x118, x101, x69); + uint32_t x121; + fiat_p256_uint1 x122; + fiat_p256_addcarryx_u32(&x121, &x122, x120, x103, x71); + uint32_t x123; + fiat_p256_uint1 x124; + fiat_p256_addcarryx_u32(&x123, &x124, x122, x105, x73); + uint32_t x125; + fiat_p256_uint1 x126; + fiat_p256_addcarryx_u32(&x125, &x126, x124, x107, (fiat_p256_uint1)x75); + uint32_t x127; + uint32_t x128; + fiat_p256_mulx_u32(&x127, &x128, x109, UINT32_C(0xffffffff)); + uint32_t x129; + uint32_t x130; + fiat_p256_mulx_u32(&x129, &x130, x109, UINT32_C(0xffffffff)); + uint32_t x131; + uint32_t x132; + fiat_p256_mulx_u32(&x131, &x132, x109, UINT32_C(0xffffffff)); + uint32_t x133; + uint32_t x134; + fiat_p256_mulx_u32(&x133, &x134, x109, UINT32_C(0xffffffff)); + uint32_t x135; + fiat_p256_uint1 x136; + fiat_p256_addcarryx_u32(&x135, &x136, 0x0, x131, x134); + uint32_t x137; + fiat_p256_uint1 x138; + fiat_p256_addcarryx_u32(&x137, &x138, x136, x129, x132); + uint32_t x139; + fiat_p256_uint1 x140; + fiat_p256_addcarryx_u32(&x139, &x140, x138, 0x0, x130); + uint32_t x141; + fiat_p256_uint1 x142; + fiat_p256_addcarryx_u32(&x141, &x142, x140, 0x0, 0x0); + uint32_t x143; + fiat_p256_uint1 x144; + fiat_p256_addcarryx_u32(&x143, &x144, 0x0, x133, x109); + uint32_t x145; + fiat_p256_uint1 x146; + fiat_p256_addcarryx_u32(&x145, &x146, x144, x135, x111); + uint32_t x147; + fiat_p256_uint1 x148; + fiat_p256_addcarryx_u32(&x147, &x148, x146, x137, x113); + uint32_t x149; + fiat_p256_uint1 x150; + fiat_p256_addcarryx_u32(&x149, &x150, x148, x139, x115); + uint32_t x151; + fiat_p256_uint1 x152; + fiat_p256_addcarryx_u32(&x151, &x152, x150, (fiat_p256_uint1)x141, x117); + uint32_t x153; + fiat_p256_uint1 x154; + fiat_p256_addcarryx_u32(&x153, &x154, x152, 0x0, x119); + uint32_t x155; + fiat_p256_uint1 x156; + fiat_p256_addcarryx_u32(&x155, &x156, x154, x109, x121); + uint32_t x157; + fiat_p256_uint1 x158; + fiat_p256_addcarryx_u32(&x157, &x158, x156, x127, x123); + uint32_t x159; + fiat_p256_uint1 x160; + fiat_p256_addcarryx_u32(&x159, &x160, x158, x128, x125); + uint32_t x161; + fiat_p256_uint1 x162; + fiat_p256_addcarryx_u32(&x161, &x162, x160, 0x0, x126); + uint32_t x163; + uint32_t x164; + fiat_p256_mulx_u32(&x163, &x164, x2, (arg2[7])); + uint32_t x165; + uint32_t x166; + fiat_p256_mulx_u32(&x165, &x166, x2, (arg2[6])); + uint32_t x167; + uint32_t x168; + fiat_p256_mulx_u32(&x167, &x168, x2, (arg2[5])); + uint32_t x169; + uint32_t x170; + fiat_p256_mulx_u32(&x169, &x170, x2, (arg2[4])); + uint32_t x171; + uint32_t x172; + fiat_p256_mulx_u32(&x171, &x172, x2, (arg2[3])); + uint32_t x173; + uint32_t x174; + fiat_p256_mulx_u32(&x173, &x174, x2, (arg2[2])); + uint32_t x175; + uint32_t x176; + fiat_p256_mulx_u32(&x175, &x176, x2, (arg2[1])); + uint32_t x177; + uint32_t x178; + fiat_p256_mulx_u32(&x177, &x178, x2, (arg2[0])); + uint32_t x179; + fiat_p256_uint1 x180; + fiat_p256_addcarryx_u32(&x179, &x180, 0x0, x175, x178); + uint32_t x181; + fiat_p256_uint1 x182; + fiat_p256_addcarryx_u32(&x181, &x182, x180, x173, x176); + uint32_t x183; + fiat_p256_uint1 x184; + fiat_p256_addcarryx_u32(&x183, &x184, x182, x171, x174); + uint32_t x185; + fiat_p256_uint1 x186; + fiat_p256_addcarryx_u32(&x185, &x186, x184, x169, x172); + uint32_t x187; + fiat_p256_uint1 x188; + fiat_p256_addcarryx_u32(&x187, &x188, x186, x167, x170); + uint32_t x189; + fiat_p256_uint1 x190; + fiat_p256_addcarryx_u32(&x189, &x190, x188, x165, x168); + uint32_t x191; + fiat_p256_uint1 x192; + fiat_p256_addcarryx_u32(&x191, &x192, x190, x163, x166); + uint32_t x193; + fiat_p256_uint1 x194; + fiat_p256_addcarryx_u32(&x193, &x194, x192, 0x0, x164); + uint32_t x195; + fiat_p256_uint1 x196; + fiat_p256_addcarryx_u32(&x195, &x196, 0x0, x177, x145); + uint32_t x197; + fiat_p256_uint1 x198; + fiat_p256_addcarryx_u32(&x197, &x198, x196, x179, x147); + uint32_t x199; + fiat_p256_uint1 x200; + fiat_p256_addcarryx_u32(&x199, &x200, x198, x181, x149); + uint32_t x201; + fiat_p256_uint1 x202; + fiat_p256_addcarryx_u32(&x201, &x202, x200, x183, x151); + uint32_t x203; + fiat_p256_uint1 x204; + fiat_p256_addcarryx_u32(&x203, &x204, x202, x185, x153); + uint32_t x205; + fiat_p256_uint1 x206; + fiat_p256_addcarryx_u32(&x205, &x206, x204, x187, x155); + uint32_t x207; + fiat_p256_uint1 x208; + fiat_p256_addcarryx_u32(&x207, &x208, x206, x189, x157); + uint32_t x209; + fiat_p256_uint1 x210; + fiat_p256_addcarryx_u32(&x209, &x210, x208, x191, x159); + uint32_t x211; + fiat_p256_uint1 x212; + fiat_p256_addcarryx_u32(&x211, &x212, x210, x193, x161); + uint32_t x213; + uint32_t x214; + fiat_p256_mulx_u32(&x213, &x214, x195, UINT32_C(0xffffffff)); + uint32_t x215; + uint32_t x216; + fiat_p256_mulx_u32(&x215, &x216, x195, UINT32_C(0xffffffff)); + uint32_t x217; + uint32_t x218; + fiat_p256_mulx_u32(&x217, &x218, x195, UINT32_C(0xffffffff)); + uint32_t x219; + uint32_t x220; + fiat_p256_mulx_u32(&x219, &x220, x195, UINT32_C(0xffffffff)); + uint32_t x221; + fiat_p256_uint1 x222; + fiat_p256_addcarryx_u32(&x221, &x222, 0x0, x217, x220); + uint32_t x223; + fiat_p256_uint1 x224; + fiat_p256_addcarryx_u32(&x223, &x224, x222, x215, x218); + uint32_t x225; + fiat_p256_uint1 x226; + fiat_p256_addcarryx_u32(&x225, &x226, x224, 0x0, x216); + uint32_t x227; + fiat_p256_uint1 x228; + fiat_p256_addcarryx_u32(&x227, &x228, x226, 0x0, 0x0); + uint32_t x229; + fiat_p256_uint1 x230; + fiat_p256_addcarryx_u32(&x229, &x230, 0x0, x219, x195); + uint32_t x231; + fiat_p256_uint1 x232; + fiat_p256_addcarryx_u32(&x231, &x232, x230, x221, x197); + uint32_t x233; + fiat_p256_uint1 x234; + fiat_p256_addcarryx_u32(&x233, &x234, x232, x223, x199); + uint32_t x235; + fiat_p256_uint1 x236; + fiat_p256_addcarryx_u32(&x235, &x236, x234, x225, x201); + uint32_t x237; + fiat_p256_uint1 x238; + fiat_p256_addcarryx_u32(&x237, &x238, x236, (fiat_p256_uint1)x227, x203); + uint32_t x239; + fiat_p256_uint1 x240; + fiat_p256_addcarryx_u32(&x239, &x240, x238, 0x0, x205); + uint32_t x241; + fiat_p256_uint1 x242; + fiat_p256_addcarryx_u32(&x241, &x242, x240, x195, x207); + uint32_t x243; + fiat_p256_uint1 x244; + fiat_p256_addcarryx_u32(&x243, &x244, x242, x213, x209); + uint32_t x245; + fiat_p256_uint1 x246; + fiat_p256_addcarryx_u32(&x245, &x246, x244, x214, x211); + uint32_t x247; + fiat_p256_uint1 x248; + fiat_p256_addcarryx_u32(&x247, &x248, x246, 0x0, x212); + uint32_t x249; + uint32_t x250; + fiat_p256_mulx_u32(&x249, &x250, x3, (arg2[7])); + uint32_t x251; + uint32_t x252; + fiat_p256_mulx_u32(&x251, &x252, x3, (arg2[6])); + uint32_t x253; + uint32_t x254; + fiat_p256_mulx_u32(&x253, &x254, x3, (arg2[5])); + uint32_t x255; + uint32_t x256; + fiat_p256_mulx_u32(&x255, &x256, x3, (arg2[4])); + uint32_t x257; + uint32_t x258; + fiat_p256_mulx_u32(&x257, &x258, x3, (arg2[3])); + uint32_t x259; + uint32_t x260; + fiat_p256_mulx_u32(&x259, &x260, x3, (arg2[2])); + uint32_t x261; + uint32_t x262; + fiat_p256_mulx_u32(&x261, &x262, x3, (arg2[1])); + uint32_t x263; + uint32_t x264; + fiat_p256_mulx_u32(&x263, &x264, x3, (arg2[0])); + uint32_t x265; + fiat_p256_uint1 x266; + fiat_p256_addcarryx_u32(&x265, &x266, 0x0, x261, x264); + uint32_t x267; + fiat_p256_uint1 x268; + fiat_p256_addcarryx_u32(&x267, &x268, x266, x259, x262); + uint32_t x269; + fiat_p256_uint1 x270; + fiat_p256_addcarryx_u32(&x269, &x270, x268, x257, x260); + uint32_t x271; + fiat_p256_uint1 x272; + fiat_p256_addcarryx_u32(&x271, &x272, x270, x255, x258); + uint32_t x273; + fiat_p256_uint1 x274; + fiat_p256_addcarryx_u32(&x273, &x274, x272, x253, x256); + uint32_t x275; + fiat_p256_uint1 x276; + fiat_p256_addcarryx_u32(&x275, &x276, x274, x251, x254); + uint32_t x277; + fiat_p256_uint1 x278; + fiat_p256_addcarryx_u32(&x277, &x278, x276, x249, x252); + uint32_t x279; + fiat_p256_uint1 x280; + fiat_p256_addcarryx_u32(&x279, &x280, x278, 0x0, x250); + uint32_t x281; + fiat_p256_uint1 x282; + fiat_p256_addcarryx_u32(&x281, &x282, 0x0, x263, x231); + uint32_t x283; + fiat_p256_uint1 x284; + fiat_p256_addcarryx_u32(&x283, &x284, x282, x265, x233); + uint32_t x285; + fiat_p256_uint1 x286; + fiat_p256_addcarryx_u32(&x285, &x286, x284, x267, x235); + uint32_t x287; + fiat_p256_uint1 x288; + fiat_p256_addcarryx_u32(&x287, &x288, x286, x269, x237); + uint32_t x289; + fiat_p256_uint1 x290; + fiat_p256_addcarryx_u32(&x289, &x290, x288, x271, x239); + uint32_t x291; + fiat_p256_uint1 x292; + fiat_p256_addcarryx_u32(&x291, &x292, x290, x273, x241); + uint32_t x293; + fiat_p256_uint1 x294; + fiat_p256_addcarryx_u32(&x293, &x294, x292, x275, x243); + uint32_t x295; + fiat_p256_uint1 x296; + fiat_p256_addcarryx_u32(&x295, &x296, x294, x277, x245); + uint32_t x297; + fiat_p256_uint1 x298; + fiat_p256_addcarryx_u32(&x297, &x298, x296, x279, x247); + uint32_t x299; + uint32_t x300; + fiat_p256_mulx_u32(&x299, &x300, x281, UINT32_C(0xffffffff)); + uint32_t x301; + uint32_t x302; + fiat_p256_mulx_u32(&x301, &x302, x281, UINT32_C(0xffffffff)); + uint32_t x303; + uint32_t x304; + fiat_p256_mulx_u32(&x303, &x304, x281, UINT32_C(0xffffffff)); + uint32_t x305; + uint32_t x306; + fiat_p256_mulx_u32(&x305, &x306, x281, UINT32_C(0xffffffff)); + uint32_t x307; + fiat_p256_uint1 x308; + fiat_p256_addcarryx_u32(&x307, &x308, 0x0, x303, x306); + uint32_t x309; + fiat_p256_uint1 x310; + fiat_p256_addcarryx_u32(&x309, &x310, x308, x301, x304); + uint32_t x311; + fiat_p256_uint1 x312; + fiat_p256_addcarryx_u32(&x311, &x312, x310, 0x0, x302); + uint32_t x313; + fiat_p256_uint1 x314; + fiat_p256_addcarryx_u32(&x313, &x314, x312, 0x0, 0x0); + uint32_t x315; + fiat_p256_uint1 x316; + fiat_p256_addcarryx_u32(&x315, &x316, 0x0, x305, x281); + uint32_t x317; + fiat_p256_uint1 x318; + fiat_p256_addcarryx_u32(&x317, &x318, x316, x307, x283); + uint32_t x319; + fiat_p256_uint1 x320; + fiat_p256_addcarryx_u32(&x319, &x320, x318, x309, x285); + uint32_t x321; + fiat_p256_uint1 x322; + fiat_p256_addcarryx_u32(&x321, &x322, x320, x311, x287); + uint32_t x323; + fiat_p256_uint1 x324; + fiat_p256_addcarryx_u32(&x323, &x324, x322, (fiat_p256_uint1)x313, x289); + uint32_t x325; + fiat_p256_uint1 x326; + fiat_p256_addcarryx_u32(&x325, &x326, x324, 0x0, x291); + uint32_t x327; + fiat_p256_uint1 x328; + fiat_p256_addcarryx_u32(&x327, &x328, x326, x281, x293); + uint32_t x329; + fiat_p256_uint1 x330; + fiat_p256_addcarryx_u32(&x329, &x330, x328, x299, x295); + uint32_t x331; + fiat_p256_uint1 x332; + fiat_p256_addcarryx_u32(&x331, &x332, x330, x300, x297); + uint32_t x333; + fiat_p256_uint1 x334; + fiat_p256_addcarryx_u32(&x333, &x334, x332, 0x0, x298); + uint32_t x335; + uint32_t x336; + fiat_p256_mulx_u32(&x335, &x336, x4, (arg2[7])); + uint32_t x337; + uint32_t x338; + fiat_p256_mulx_u32(&x337, &x338, x4, (arg2[6])); + uint32_t x339; + uint32_t x340; + fiat_p256_mulx_u32(&x339, &x340, x4, (arg2[5])); + uint32_t x341; + uint32_t x342; + fiat_p256_mulx_u32(&x341, &x342, x4, (arg2[4])); + uint32_t x343; + uint32_t x344; + fiat_p256_mulx_u32(&x343, &x344, x4, (arg2[3])); + uint32_t x345; + uint32_t x346; + fiat_p256_mulx_u32(&x345, &x346, x4, (arg2[2])); + uint32_t x347; + uint32_t x348; + fiat_p256_mulx_u32(&x347, &x348, x4, (arg2[1])); + uint32_t x349; + uint32_t x350; + fiat_p256_mulx_u32(&x349, &x350, x4, (arg2[0])); + uint32_t x351; + fiat_p256_uint1 x352; + fiat_p256_addcarryx_u32(&x351, &x352, 0x0, x347, x350); + uint32_t x353; + fiat_p256_uint1 x354; + fiat_p256_addcarryx_u32(&x353, &x354, x352, x345, x348); + uint32_t x355; + fiat_p256_uint1 x356; + fiat_p256_addcarryx_u32(&x355, &x356, x354, x343, x346); + uint32_t x357; + fiat_p256_uint1 x358; + fiat_p256_addcarryx_u32(&x357, &x358, x356, x341, x344); + uint32_t x359; + fiat_p256_uint1 x360; + fiat_p256_addcarryx_u32(&x359, &x360, x358, x339, x342); + uint32_t x361; + fiat_p256_uint1 x362; + fiat_p256_addcarryx_u32(&x361, &x362, x360, x337, x340); + uint32_t x363; + fiat_p256_uint1 x364; + fiat_p256_addcarryx_u32(&x363, &x364, x362, x335, x338); + uint32_t x365; + fiat_p256_uint1 x366; + fiat_p256_addcarryx_u32(&x365, &x366, x364, 0x0, x336); + uint32_t x367; + fiat_p256_uint1 x368; + fiat_p256_addcarryx_u32(&x367, &x368, 0x0, x349, x317); + uint32_t x369; + fiat_p256_uint1 x370; + fiat_p256_addcarryx_u32(&x369, &x370, x368, x351, x319); + uint32_t x371; + fiat_p256_uint1 x372; + fiat_p256_addcarryx_u32(&x371, &x372, x370, x353, x321); + uint32_t x373; + fiat_p256_uint1 x374; + fiat_p256_addcarryx_u32(&x373, &x374, x372, x355, x323); + uint32_t x375; + fiat_p256_uint1 x376; + fiat_p256_addcarryx_u32(&x375, &x376, x374, x357, x325); + uint32_t x377; + fiat_p256_uint1 x378; + fiat_p256_addcarryx_u32(&x377, &x378, x376, x359, x327); + uint32_t x379; + fiat_p256_uint1 x380; + fiat_p256_addcarryx_u32(&x379, &x380, x378, x361, x329); + uint32_t x381; + fiat_p256_uint1 x382; + fiat_p256_addcarryx_u32(&x381, &x382, x380, x363, x331); + uint32_t x383; + fiat_p256_uint1 x384; + fiat_p256_addcarryx_u32(&x383, &x384, x382, x365, x333); + uint32_t x385; + uint32_t x386; + fiat_p256_mulx_u32(&x385, &x386, x367, UINT32_C(0xffffffff)); + uint32_t x387; + uint32_t x388; + fiat_p256_mulx_u32(&x387, &x388, x367, UINT32_C(0xffffffff)); + uint32_t x389; + uint32_t x390; + fiat_p256_mulx_u32(&x389, &x390, x367, UINT32_C(0xffffffff)); + uint32_t x391; + uint32_t x392; + fiat_p256_mulx_u32(&x391, &x392, x367, UINT32_C(0xffffffff)); + uint32_t x393; + fiat_p256_uint1 x394; + fiat_p256_addcarryx_u32(&x393, &x394, 0x0, x389, x392); + uint32_t x395; + fiat_p256_uint1 x396; + fiat_p256_addcarryx_u32(&x395, &x396, x394, x387, x390); + uint32_t x397; + fiat_p256_uint1 x398; + fiat_p256_addcarryx_u32(&x397, &x398, x396, 0x0, x388); + uint32_t x399; + fiat_p256_uint1 x400; + fiat_p256_addcarryx_u32(&x399, &x400, x398, 0x0, 0x0); + uint32_t x401; + fiat_p256_uint1 x402; + fiat_p256_addcarryx_u32(&x401, &x402, 0x0, x391, x367); + uint32_t x403; + fiat_p256_uint1 x404; + fiat_p256_addcarryx_u32(&x403, &x404, x402, x393, x369); + uint32_t x405; + fiat_p256_uint1 x406; + fiat_p256_addcarryx_u32(&x405, &x406, x404, x395, x371); + uint32_t x407; + fiat_p256_uint1 x408; + fiat_p256_addcarryx_u32(&x407, &x408, x406, x397, x373); + uint32_t x409; + fiat_p256_uint1 x410; + fiat_p256_addcarryx_u32(&x409, &x410, x408, (fiat_p256_uint1)x399, x375); + uint32_t x411; + fiat_p256_uint1 x412; + fiat_p256_addcarryx_u32(&x411, &x412, x410, 0x0, x377); + uint32_t x413; + fiat_p256_uint1 x414; + fiat_p256_addcarryx_u32(&x413, &x414, x412, x367, x379); + uint32_t x415; + fiat_p256_uint1 x416; + fiat_p256_addcarryx_u32(&x415, &x416, x414, x385, x381); + uint32_t x417; + fiat_p256_uint1 x418; + fiat_p256_addcarryx_u32(&x417, &x418, x416, x386, x383); + uint32_t x419; + fiat_p256_uint1 x420; + fiat_p256_addcarryx_u32(&x419, &x420, x418, 0x0, x384); + uint32_t x421; + uint32_t x422; + fiat_p256_mulx_u32(&x421, &x422, x5, (arg2[7])); + uint32_t x423; + uint32_t x424; + fiat_p256_mulx_u32(&x423, &x424, x5, (arg2[6])); + uint32_t x425; + uint32_t x426; + fiat_p256_mulx_u32(&x425, &x426, x5, (arg2[5])); + uint32_t x427; + uint32_t x428; + fiat_p256_mulx_u32(&x427, &x428, x5, (arg2[4])); + uint32_t x429; + uint32_t x430; + fiat_p256_mulx_u32(&x429, &x430, x5, (arg2[3])); + uint32_t x431; + uint32_t x432; + fiat_p256_mulx_u32(&x431, &x432, x5, (arg2[2])); + uint32_t x433; + uint32_t x434; + fiat_p256_mulx_u32(&x433, &x434, x5, (arg2[1])); + uint32_t x435; + uint32_t x436; + fiat_p256_mulx_u32(&x435, &x436, x5, (arg2[0])); + uint32_t x437; + fiat_p256_uint1 x438; + fiat_p256_addcarryx_u32(&x437, &x438, 0x0, x433, x436); + uint32_t x439; + fiat_p256_uint1 x440; + fiat_p256_addcarryx_u32(&x439, &x440, x438, x431, x434); + uint32_t x441; + fiat_p256_uint1 x442; + fiat_p256_addcarryx_u32(&x441, &x442, x440, x429, x432); + uint32_t x443; + fiat_p256_uint1 x444; + fiat_p256_addcarryx_u32(&x443, &x444, x442, x427, x430); + uint32_t x445; + fiat_p256_uint1 x446; + fiat_p256_addcarryx_u32(&x445, &x446, x444, x425, x428); + uint32_t x447; + fiat_p256_uint1 x448; + fiat_p256_addcarryx_u32(&x447, &x448, x446, x423, x426); + uint32_t x449; + fiat_p256_uint1 x450; + fiat_p256_addcarryx_u32(&x449, &x450, x448, x421, x424); + uint32_t x451; + fiat_p256_uint1 x452; + fiat_p256_addcarryx_u32(&x451, &x452, x450, 0x0, x422); + uint32_t x453; + fiat_p256_uint1 x454; + fiat_p256_addcarryx_u32(&x453, &x454, 0x0, x435, x403); + uint32_t x455; + fiat_p256_uint1 x456; + fiat_p256_addcarryx_u32(&x455, &x456, x454, x437, x405); + uint32_t x457; + fiat_p256_uint1 x458; + fiat_p256_addcarryx_u32(&x457, &x458, x456, x439, x407); + uint32_t x459; + fiat_p256_uint1 x460; + fiat_p256_addcarryx_u32(&x459, &x460, x458, x441, x409); + uint32_t x461; + fiat_p256_uint1 x462; + fiat_p256_addcarryx_u32(&x461, &x462, x460, x443, x411); + uint32_t x463; + fiat_p256_uint1 x464; + fiat_p256_addcarryx_u32(&x463, &x464, x462, x445, x413); + uint32_t x465; + fiat_p256_uint1 x466; + fiat_p256_addcarryx_u32(&x465, &x466, x464, x447, x415); + uint32_t x467; + fiat_p256_uint1 x468; + fiat_p256_addcarryx_u32(&x467, &x468, x466, x449, x417); + uint32_t x469; + fiat_p256_uint1 x470; + fiat_p256_addcarryx_u32(&x469, &x470, x468, x451, x419); + uint32_t x471; + uint32_t x472; + fiat_p256_mulx_u32(&x471, &x472, x453, UINT32_C(0xffffffff)); + uint32_t x473; + uint32_t x474; + fiat_p256_mulx_u32(&x473, &x474, x453, UINT32_C(0xffffffff)); + uint32_t x475; + uint32_t x476; + fiat_p256_mulx_u32(&x475, &x476, x453, UINT32_C(0xffffffff)); + uint32_t x477; + uint32_t x478; + fiat_p256_mulx_u32(&x477, &x478, x453, UINT32_C(0xffffffff)); + uint32_t x479; + fiat_p256_uint1 x480; + fiat_p256_addcarryx_u32(&x479, &x480, 0x0, x475, x478); + uint32_t x481; + fiat_p256_uint1 x482; + fiat_p256_addcarryx_u32(&x481, &x482, x480, x473, x476); + uint32_t x483; + fiat_p256_uint1 x484; + fiat_p256_addcarryx_u32(&x483, &x484, x482, 0x0, x474); + uint32_t x485; + fiat_p256_uint1 x486; + fiat_p256_addcarryx_u32(&x485, &x486, x484, 0x0, 0x0); + uint32_t x487; + fiat_p256_uint1 x488; + fiat_p256_addcarryx_u32(&x487, &x488, 0x0, x477, x453); + uint32_t x489; + fiat_p256_uint1 x490; + fiat_p256_addcarryx_u32(&x489, &x490, x488, x479, x455); + uint32_t x491; + fiat_p256_uint1 x492; + fiat_p256_addcarryx_u32(&x491, &x492, x490, x481, x457); + uint32_t x493; + fiat_p256_uint1 x494; + fiat_p256_addcarryx_u32(&x493, &x494, x492, x483, x459); + uint32_t x495; + fiat_p256_uint1 x496; + fiat_p256_addcarryx_u32(&x495, &x496, x494, (fiat_p256_uint1)x485, x461); + uint32_t x497; + fiat_p256_uint1 x498; + fiat_p256_addcarryx_u32(&x497, &x498, x496, 0x0, x463); + uint32_t x499; + fiat_p256_uint1 x500; + fiat_p256_addcarryx_u32(&x499, &x500, x498, x453, x465); + uint32_t x501; + fiat_p256_uint1 x502; + fiat_p256_addcarryx_u32(&x501, &x502, x500, x471, x467); + uint32_t x503; + fiat_p256_uint1 x504; + fiat_p256_addcarryx_u32(&x503, &x504, x502, x472, x469); + uint32_t x505; + fiat_p256_uint1 x506; + fiat_p256_addcarryx_u32(&x505, &x506, x504, 0x0, x470); + uint32_t x507; + uint32_t x508; + fiat_p256_mulx_u32(&x507, &x508, x6, (arg2[7])); + uint32_t x509; + uint32_t x510; + fiat_p256_mulx_u32(&x509, &x510, x6, (arg2[6])); + uint32_t x511; + uint32_t x512; + fiat_p256_mulx_u32(&x511, &x512, x6, (arg2[5])); + uint32_t x513; + uint32_t x514; + fiat_p256_mulx_u32(&x513, &x514, x6, (arg2[4])); + uint32_t x515; + uint32_t x516; + fiat_p256_mulx_u32(&x515, &x516, x6, (arg2[3])); + uint32_t x517; + uint32_t x518; + fiat_p256_mulx_u32(&x517, &x518, x6, (arg2[2])); + uint32_t x519; + uint32_t x520; + fiat_p256_mulx_u32(&x519, &x520, x6, (arg2[1])); + uint32_t x521; + uint32_t x522; + fiat_p256_mulx_u32(&x521, &x522, x6, (arg2[0])); + uint32_t x523; + fiat_p256_uint1 x524; + fiat_p256_addcarryx_u32(&x523, &x524, 0x0, x519, x522); + uint32_t x525; + fiat_p256_uint1 x526; + fiat_p256_addcarryx_u32(&x525, &x526, x524, x517, x520); + uint32_t x527; + fiat_p256_uint1 x528; + fiat_p256_addcarryx_u32(&x527, &x528, x526, x515, x518); + uint32_t x529; + fiat_p256_uint1 x530; + fiat_p256_addcarryx_u32(&x529, &x530, x528, x513, x516); + uint32_t x531; + fiat_p256_uint1 x532; + fiat_p256_addcarryx_u32(&x531, &x532, x530, x511, x514); + uint32_t x533; + fiat_p256_uint1 x534; + fiat_p256_addcarryx_u32(&x533, &x534, x532, x509, x512); + uint32_t x535; + fiat_p256_uint1 x536; + fiat_p256_addcarryx_u32(&x535, &x536, x534, x507, x510); + uint32_t x537; + fiat_p256_uint1 x538; + fiat_p256_addcarryx_u32(&x537, &x538, x536, 0x0, x508); + uint32_t x539; + fiat_p256_uint1 x540; + fiat_p256_addcarryx_u32(&x539, &x540, 0x0, x521, x489); + uint32_t x541; + fiat_p256_uint1 x542; + fiat_p256_addcarryx_u32(&x541, &x542, x540, x523, x491); + uint32_t x543; + fiat_p256_uint1 x544; + fiat_p256_addcarryx_u32(&x543, &x544, x542, x525, x493); + uint32_t x545; + fiat_p256_uint1 x546; + fiat_p256_addcarryx_u32(&x545, &x546, x544, x527, x495); + uint32_t x547; + fiat_p256_uint1 x548; + fiat_p256_addcarryx_u32(&x547, &x548, x546, x529, x497); + uint32_t x549; + fiat_p256_uint1 x550; + fiat_p256_addcarryx_u32(&x549, &x550, x548, x531, x499); + uint32_t x551; + fiat_p256_uint1 x552; + fiat_p256_addcarryx_u32(&x551, &x552, x550, x533, x501); + uint32_t x553; + fiat_p256_uint1 x554; + fiat_p256_addcarryx_u32(&x553, &x554, x552, x535, x503); + uint32_t x555; + fiat_p256_uint1 x556; + fiat_p256_addcarryx_u32(&x555, &x556, x554, x537, x505); + uint32_t x557; + uint32_t x558; + fiat_p256_mulx_u32(&x557, &x558, x539, UINT32_C(0xffffffff)); + uint32_t x559; + uint32_t x560; + fiat_p256_mulx_u32(&x559, &x560, x539, UINT32_C(0xffffffff)); + uint32_t x561; + uint32_t x562; + fiat_p256_mulx_u32(&x561, &x562, x539, UINT32_C(0xffffffff)); + uint32_t x563; + uint32_t x564; + fiat_p256_mulx_u32(&x563, &x564, x539, UINT32_C(0xffffffff)); + uint32_t x565; + fiat_p256_uint1 x566; + fiat_p256_addcarryx_u32(&x565, &x566, 0x0, x561, x564); + uint32_t x567; + fiat_p256_uint1 x568; + fiat_p256_addcarryx_u32(&x567, &x568, x566, x559, x562); + uint32_t x569; + fiat_p256_uint1 x570; + fiat_p256_addcarryx_u32(&x569, &x570, x568, 0x0, x560); + uint32_t x571; + fiat_p256_uint1 x572; + fiat_p256_addcarryx_u32(&x571, &x572, x570, 0x0, 0x0); + uint32_t x573; + fiat_p256_uint1 x574; + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x563, x539); + uint32_t x575; + fiat_p256_uint1 x576; + fiat_p256_addcarryx_u32(&x575, &x576, x574, x565, x541); + uint32_t x577; + fiat_p256_uint1 x578; + fiat_p256_addcarryx_u32(&x577, &x578, x576, x567, x543); + uint32_t x579; + fiat_p256_uint1 x580; + fiat_p256_addcarryx_u32(&x579, &x580, x578, x569, x545); + uint32_t x581; + fiat_p256_uint1 x582; + fiat_p256_addcarryx_u32(&x581, &x582, x580, (fiat_p256_uint1)x571, x547); + uint32_t x583; + fiat_p256_uint1 x584; + fiat_p256_addcarryx_u32(&x583, &x584, x582, 0x0, x549); + uint32_t x585; + fiat_p256_uint1 x586; + fiat_p256_addcarryx_u32(&x585, &x586, x584, x539, x551); + uint32_t x587; + fiat_p256_uint1 x588; + fiat_p256_addcarryx_u32(&x587, &x588, x586, x557, x553); + uint32_t x589; + fiat_p256_uint1 x590; + fiat_p256_addcarryx_u32(&x589, &x590, x588, x558, x555); + uint32_t x591; + fiat_p256_uint1 x592; + fiat_p256_addcarryx_u32(&x591, &x592, x590, 0x0, x556); + uint32_t x593; + uint32_t x594; + fiat_p256_mulx_u32(&x593, &x594, x7, (arg2[7])); + uint32_t x595; + uint32_t x596; + fiat_p256_mulx_u32(&x595, &x596, x7, (arg2[6])); + uint32_t x597; + uint32_t x598; + fiat_p256_mulx_u32(&x597, &x598, x7, (arg2[5])); + uint32_t x599; + uint32_t x600; + fiat_p256_mulx_u32(&x599, &x600, x7, (arg2[4])); + uint32_t x601; + uint32_t x602; + fiat_p256_mulx_u32(&x601, &x602, x7, (arg2[3])); + uint32_t x603; + uint32_t x604; + fiat_p256_mulx_u32(&x603, &x604, x7, (arg2[2])); + uint32_t x605; + uint32_t x606; + fiat_p256_mulx_u32(&x605, &x606, x7, (arg2[1])); + uint32_t x607; + uint32_t x608; + fiat_p256_mulx_u32(&x607, &x608, x7, (arg2[0])); + uint32_t x609; + fiat_p256_uint1 x610; + fiat_p256_addcarryx_u32(&x609, &x610, 0x0, x605, x608); + uint32_t x611; + fiat_p256_uint1 x612; + fiat_p256_addcarryx_u32(&x611, &x612, x610, x603, x606); + uint32_t x613; + fiat_p256_uint1 x614; + fiat_p256_addcarryx_u32(&x613, &x614, x612, x601, x604); + uint32_t x615; + fiat_p256_uint1 x616; + fiat_p256_addcarryx_u32(&x615, &x616, x614, x599, x602); + uint32_t x617; + fiat_p256_uint1 x618; + fiat_p256_addcarryx_u32(&x617, &x618, x616, x597, x600); + uint32_t x619; + fiat_p256_uint1 x620; + fiat_p256_addcarryx_u32(&x619, &x620, x618, x595, x598); + uint32_t x621; + fiat_p256_uint1 x622; + fiat_p256_addcarryx_u32(&x621, &x622, x620, x593, x596); + uint32_t x623; + fiat_p256_uint1 x624; + fiat_p256_addcarryx_u32(&x623, &x624, x622, 0x0, x594); + uint32_t x625; + fiat_p256_uint1 x626; + fiat_p256_addcarryx_u32(&x625, &x626, 0x0, x607, x575); + uint32_t x627; + fiat_p256_uint1 x628; + fiat_p256_addcarryx_u32(&x627, &x628, x626, x609, x577); + uint32_t x629; + fiat_p256_uint1 x630; + fiat_p256_addcarryx_u32(&x629, &x630, x628, x611, x579); + uint32_t x631; + fiat_p256_uint1 x632; + fiat_p256_addcarryx_u32(&x631, &x632, x630, x613, x581); + uint32_t x633; + fiat_p256_uint1 x634; + fiat_p256_addcarryx_u32(&x633, &x634, x632, x615, x583); + uint32_t x635; + fiat_p256_uint1 x636; + fiat_p256_addcarryx_u32(&x635, &x636, x634, x617, x585); + uint32_t x637; + fiat_p256_uint1 x638; + fiat_p256_addcarryx_u32(&x637, &x638, x636, x619, x587); + uint32_t x639; + fiat_p256_uint1 x640; + fiat_p256_addcarryx_u32(&x639, &x640, x638, x621, x589); + uint32_t x641; + fiat_p256_uint1 x642; + fiat_p256_addcarryx_u32(&x641, &x642, x640, x623, x591); + uint32_t x643; + uint32_t x644; + fiat_p256_mulx_u32(&x643, &x644, x625, UINT32_C(0xffffffff)); + uint32_t x645; + uint32_t x646; + fiat_p256_mulx_u32(&x645, &x646, x625, UINT32_C(0xffffffff)); + uint32_t x647; + uint32_t x648; + fiat_p256_mulx_u32(&x647, &x648, x625, UINT32_C(0xffffffff)); + uint32_t x649; + uint32_t x650; + fiat_p256_mulx_u32(&x649, &x650, x625, UINT32_C(0xffffffff)); + uint32_t x651; + fiat_p256_uint1 x652; + fiat_p256_addcarryx_u32(&x651, &x652, 0x0, x647, x650); + uint32_t x653; + fiat_p256_uint1 x654; + fiat_p256_addcarryx_u32(&x653, &x654, x652, x645, x648); + uint32_t x655; + fiat_p256_uint1 x656; + fiat_p256_addcarryx_u32(&x655, &x656, x654, 0x0, x646); + uint32_t x657; + fiat_p256_uint1 x658; + fiat_p256_addcarryx_u32(&x657, &x658, x656, 0x0, 0x0); + uint32_t x659; + fiat_p256_uint1 x660; + fiat_p256_addcarryx_u32(&x659, &x660, 0x0, x649, x625); + uint32_t x661; + fiat_p256_uint1 x662; + fiat_p256_addcarryx_u32(&x661, &x662, x660, x651, x627); + uint32_t x663; + fiat_p256_uint1 x664; + fiat_p256_addcarryx_u32(&x663, &x664, x662, x653, x629); + uint32_t x665; + fiat_p256_uint1 x666; + fiat_p256_addcarryx_u32(&x665, &x666, x664, x655, x631); + uint32_t x667; + fiat_p256_uint1 x668; + fiat_p256_addcarryx_u32(&x667, &x668, x666, (fiat_p256_uint1)x657, x633); + uint32_t x669; + fiat_p256_uint1 x670; + fiat_p256_addcarryx_u32(&x669, &x670, x668, 0x0, x635); + uint32_t x671; + fiat_p256_uint1 x672; + fiat_p256_addcarryx_u32(&x671, &x672, x670, x625, x637); + uint32_t x673; + fiat_p256_uint1 x674; + fiat_p256_addcarryx_u32(&x673, &x674, x672, x643, x639); + uint32_t x675; + fiat_p256_uint1 x676; + fiat_p256_addcarryx_u32(&x675, &x676, x674, x644, x641); + uint32_t x677; + fiat_p256_uint1 x678; + fiat_p256_addcarryx_u32(&x677, &x678, x676, 0x0, x642); + uint32_t x679; + fiat_p256_uint1 x680; + fiat_p256_subborrowx_u32(&x679, &x680, 0x0, x661, UINT32_C(0xffffffff)); + uint32_t x681; + fiat_p256_uint1 x682; + fiat_p256_subborrowx_u32(&x681, &x682, x680, x663, UINT32_C(0xffffffff)); + uint32_t x683; + fiat_p256_uint1 x684; + fiat_p256_subborrowx_u32(&x683, &x684, x682, x665, UINT32_C(0xffffffff)); + uint32_t x685; + fiat_p256_uint1 x686; + fiat_p256_subborrowx_u32(&x685, &x686, x684, x667, 0x0); + uint32_t x687; + fiat_p256_uint1 x688; + fiat_p256_subborrowx_u32(&x687, &x688, x686, x669, 0x0); + uint32_t x689; + fiat_p256_uint1 x690; + fiat_p256_subborrowx_u32(&x689, &x690, x688, x671, 0x0); + uint32_t x691; + fiat_p256_uint1 x692; + fiat_p256_subborrowx_u32(&x691, &x692, x690, x673, 0x1); + uint32_t x693; + fiat_p256_uint1 x694; + fiat_p256_subborrowx_u32(&x693, &x694, x692, x675, UINT32_C(0xffffffff)); + uint32_t x695; + fiat_p256_uint1 x696; + fiat_p256_subborrowx_u32(&x695, &x696, x694, x677, 0x0); + uint32_t x697; + fiat_p256_cmovznz_u32(&x697, x696, x679, x661); + uint32_t x698; + fiat_p256_cmovznz_u32(&x698, x696, x681, x663); + uint32_t x699; + fiat_p256_cmovznz_u32(&x699, x696, x683, x665); + uint32_t x700; + fiat_p256_cmovznz_u32(&x700, x696, x685, x667); + uint32_t x701; + fiat_p256_cmovznz_u32(&x701, x696, x687, x669); + uint32_t x702; + fiat_p256_cmovznz_u32(&x702, x696, x689, x671); + uint32_t x703; + fiat_p256_cmovznz_u32(&x703, x696, x691, x673); + uint32_t x704; + fiat_p256_cmovznz_u32(&x704, x696, x693, x675); + out1[0] = x697; + out1[1] = x698; + out1[2] = x699; + out1[3] = x700; + out1[4] = x701; + out1[5] = x702; + out1[6] = x703; + out1[7] = x704; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_square(uint32_t out1[8], const uint32_t arg1[8]) { + uint32_t x1 = (arg1[1]); + uint32_t x2 = (arg1[2]); + uint32_t x3 = (arg1[3]); + uint32_t x4 = (arg1[4]); + uint32_t x5 = (arg1[5]); + uint32_t x6 = (arg1[6]); + uint32_t x7 = (arg1[7]); + uint32_t x8 = (arg1[0]); + uint32_t x9; + uint32_t x10; + fiat_p256_mulx_u32(&x9, &x10, x8, (arg1[7])); + uint32_t x11; + uint32_t x12; + fiat_p256_mulx_u32(&x11, &x12, x8, (arg1[6])); + uint32_t x13; + uint32_t x14; + fiat_p256_mulx_u32(&x13, &x14, x8, (arg1[5])); + uint32_t x15; + uint32_t x16; + fiat_p256_mulx_u32(&x15, &x16, x8, (arg1[4])); + uint32_t x17; + uint32_t x18; + fiat_p256_mulx_u32(&x17, &x18, x8, (arg1[3])); + uint32_t x19; + uint32_t x20; + fiat_p256_mulx_u32(&x19, &x20, x8, (arg1[2])); + uint32_t x21; + uint32_t x22; + fiat_p256_mulx_u32(&x21, &x22, x8, (arg1[1])); + uint32_t x23; + uint32_t x24; + fiat_p256_mulx_u32(&x23, &x24, x8, (arg1[0])); + uint32_t x25; + fiat_p256_uint1 x26; + fiat_p256_addcarryx_u32(&x25, &x26, 0x0, x21, x24); + uint32_t x27; + fiat_p256_uint1 x28; + fiat_p256_addcarryx_u32(&x27, &x28, x26, x19, x22); + uint32_t x29; + fiat_p256_uint1 x30; + fiat_p256_addcarryx_u32(&x29, &x30, x28, x17, x20); + uint32_t x31; + fiat_p256_uint1 x32; + fiat_p256_addcarryx_u32(&x31, &x32, x30, x15, x18); + uint32_t x33; + fiat_p256_uint1 x34; + fiat_p256_addcarryx_u32(&x33, &x34, x32, x13, x16); + uint32_t x35; + fiat_p256_uint1 x36; + fiat_p256_addcarryx_u32(&x35, &x36, x34, x11, x14); + uint32_t x37; + fiat_p256_uint1 x38; + fiat_p256_addcarryx_u32(&x37, &x38, x36, x9, x12); + uint32_t x39; + fiat_p256_uint1 x40; + fiat_p256_addcarryx_u32(&x39, &x40, x38, 0x0, x10); + uint32_t x41; + uint32_t x42; + fiat_p256_mulx_u32(&x41, &x42, x23, UINT32_C(0xffffffff)); + uint32_t x43; + uint32_t x44; + fiat_p256_mulx_u32(&x43, &x44, x23, UINT32_C(0xffffffff)); + uint32_t x45; + uint32_t x46; + fiat_p256_mulx_u32(&x45, &x46, x23, UINT32_C(0xffffffff)); + uint32_t x47; + uint32_t x48; + fiat_p256_mulx_u32(&x47, &x48, x23, UINT32_C(0xffffffff)); + uint32_t x49; + fiat_p256_uint1 x50; + fiat_p256_addcarryx_u32(&x49, &x50, 0x0, x45, x48); + uint32_t x51; + fiat_p256_uint1 x52; + fiat_p256_addcarryx_u32(&x51, &x52, x50, x43, x46); + uint32_t x53; + fiat_p256_uint1 x54; + fiat_p256_addcarryx_u32(&x53, &x54, x52, 0x0, x44); + uint32_t x55; + fiat_p256_uint1 x56; + fiat_p256_addcarryx_u32(&x55, &x56, x54, 0x0, 0x0); + uint32_t x57; + fiat_p256_uint1 x58; + fiat_p256_addcarryx_u32(&x57, &x58, 0x0, x47, x23); + uint32_t x59; + fiat_p256_uint1 x60; + fiat_p256_addcarryx_u32(&x59, &x60, x58, x49, x25); + uint32_t x61; + fiat_p256_uint1 x62; + fiat_p256_addcarryx_u32(&x61, &x62, x60, x51, x27); + uint32_t x63; + fiat_p256_uint1 x64; + fiat_p256_addcarryx_u32(&x63, &x64, x62, x53, x29); + uint32_t x65; + fiat_p256_uint1 x66; + fiat_p256_addcarryx_u32(&x65, &x66, x64, (fiat_p256_uint1)x55, x31); + uint32_t x67; + fiat_p256_uint1 x68; + fiat_p256_addcarryx_u32(&x67, &x68, x66, 0x0, x33); + uint32_t x69; + fiat_p256_uint1 x70; + fiat_p256_addcarryx_u32(&x69, &x70, x68, x23, x35); + uint32_t x71; + fiat_p256_uint1 x72; + fiat_p256_addcarryx_u32(&x71, &x72, x70, x41, x37); + uint32_t x73; + fiat_p256_uint1 x74; + fiat_p256_addcarryx_u32(&x73, &x74, x72, x42, x39); + uint32_t x75; + fiat_p256_uint1 x76; + fiat_p256_addcarryx_u32(&x75, &x76, x74, 0x0, 0x0); + uint32_t x77; + uint32_t x78; + fiat_p256_mulx_u32(&x77, &x78, x1, (arg1[7])); + uint32_t x79; + uint32_t x80; + fiat_p256_mulx_u32(&x79, &x80, x1, (arg1[6])); + uint32_t x81; + uint32_t x82; + fiat_p256_mulx_u32(&x81, &x82, x1, (arg1[5])); + uint32_t x83; + uint32_t x84; + fiat_p256_mulx_u32(&x83, &x84, x1, (arg1[4])); + uint32_t x85; + uint32_t x86; + fiat_p256_mulx_u32(&x85, &x86, x1, (arg1[3])); + uint32_t x87; + uint32_t x88; + fiat_p256_mulx_u32(&x87, &x88, x1, (arg1[2])); + uint32_t x89; + uint32_t x90; + fiat_p256_mulx_u32(&x89, &x90, x1, (arg1[1])); + uint32_t x91; + uint32_t x92; + fiat_p256_mulx_u32(&x91, &x92, x1, (arg1[0])); + uint32_t x93; + fiat_p256_uint1 x94; + fiat_p256_addcarryx_u32(&x93, &x94, 0x0, x89, x92); + uint32_t x95; + fiat_p256_uint1 x96; + fiat_p256_addcarryx_u32(&x95, &x96, x94, x87, x90); + uint32_t x97; + fiat_p256_uint1 x98; + fiat_p256_addcarryx_u32(&x97, &x98, x96, x85, x88); + uint32_t x99; + fiat_p256_uint1 x100; + fiat_p256_addcarryx_u32(&x99, &x100, x98, x83, x86); + uint32_t x101; + fiat_p256_uint1 x102; + fiat_p256_addcarryx_u32(&x101, &x102, x100, x81, x84); + uint32_t x103; + fiat_p256_uint1 x104; + fiat_p256_addcarryx_u32(&x103, &x104, x102, x79, x82); + uint32_t x105; + fiat_p256_uint1 x106; + fiat_p256_addcarryx_u32(&x105, &x106, x104, x77, x80); + uint32_t x107; + fiat_p256_uint1 x108; + fiat_p256_addcarryx_u32(&x107, &x108, x106, 0x0, x78); + uint32_t x109; + fiat_p256_uint1 x110; + fiat_p256_addcarryx_u32(&x109, &x110, 0x0, x91, x59); + uint32_t x111; + fiat_p256_uint1 x112; + fiat_p256_addcarryx_u32(&x111, &x112, x110, x93, x61); + uint32_t x113; + fiat_p256_uint1 x114; + fiat_p256_addcarryx_u32(&x113, &x114, x112, x95, x63); + uint32_t x115; + fiat_p256_uint1 x116; + fiat_p256_addcarryx_u32(&x115, &x116, x114, x97, x65); + uint32_t x117; + fiat_p256_uint1 x118; + fiat_p256_addcarryx_u32(&x117, &x118, x116, x99, x67); + uint32_t x119; + fiat_p256_uint1 x120; + fiat_p256_addcarryx_u32(&x119, &x120, x118, x101, x69); + uint32_t x121; + fiat_p256_uint1 x122; + fiat_p256_addcarryx_u32(&x121, &x122, x120, x103, x71); + uint32_t x123; + fiat_p256_uint1 x124; + fiat_p256_addcarryx_u32(&x123, &x124, x122, x105, x73); + uint32_t x125; + fiat_p256_uint1 x126; + fiat_p256_addcarryx_u32(&x125, &x126, x124, x107, (fiat_p256_uint1)x75); + uint32_t x127; + uint32_t x128; + fiat_p256_mulx_u32(&x127, &x128, x109, UINT32_C(0xffffffff)); + uint32_t x129; + uint32_t x130; + fiat_p256_mulx_u32(&x129, &x130, x109, UINT32_C(0xffffffff)); + uint32_t x131; + uint32_t x132; + fiat_p256_mulx_u32(&x131, &x132, x109, UINT32_C(0xffffffff)); + uint32_t x133; + uint32_t x134; + fiat_p256_mulx_u32(&x133, &x134, x109, UINT32_C(0xffffffff)); + uint32_t x135; + fiat_p256_uint1 x136; + fiat_p256_addcarryx_u32(&x135, &x136, 0x0, x131, x134); + uint32_t x137; + fiat_p256_uint1 x138; + fiat_p256_addcarryx_u32(&x137, &x138, x136, x129, x132); + uint32_t x139; + fiat_p256_uint1 x140; + fiat_p256_addcarryx_u32(&x139, &x140, x138, 0x0, x130); + uint32_t x141; + fiat_p256_uint1 x142; + fiat_p256_addcarryx_u32(&x141, &x142, x140, 0x0, 0x0); + uint32_t x143; + fiat_p256_uint1 x144; + fiat_p256_addcarryx_u32(&x143, &x144, 0x0, x133, x109); + uint32_t x145; + fiat_p256_uint1 x146; + fiat_p256_addcarryx_u32(&x145, &x146, x144, x135, x111); + uint32_t x147; + fiat_p256_uint1 x148; + fiat_p256_addcarryx_u32(&x147, &x148, x146, x137, x113); + uint32_t x149; + fiat_p256_uint1 x150; + fiat_p256_addcarryx_u32(&x149, &x150, x148, x139, x115); + uint32_t x151; + fiat_p256_uint1 x152; + fiat_p256_addcarryx_u32(&x151, &x152, x150, (fiat_p256_uint1)x141, x117); + uint32_t x153; + fiat_p256_uint1 x154; + fiat_p256_addcarryx_u32(&x153, &x154, x152, 0x0, x119); + uint32_t x155; + fiat_p256_uint1 x156; + fiat_p256_addcarryx_u32(&x155, &x156, x154, x109, x121); + uint32_t x157; + fiat_p256_uint1 x158; + fiat_p256_addcarryx_u32(&x157, &x158, x156, x127, x123); + uint32_t x159; + fiat_p256_uint1 x160; + fiat_p256_addcarryx_u32(&x159, &x160, x158, x128, x125); + uint32_t x161; + fiat_p256_uint1 x162; + fiat_p256_addcarryx_u32(&x161, &x162, x160, 0x0, x126); + uint32_t x163; + uint32_t x164; + fiat_p256_mulx_u32(&x163, &x164, x2, (arg1[7])); + uint32_t x165; + uint32_t x166; + fiat_p256_mulx_u32(&x165, &x166, x2, (arg1[6])); + uint32_t x167; + uint32_t x168; + fiat_p256_mulx_u32(&x167, &x168, x2, (arg1[5])); + uint32_t x169; + uint32_t x170; + fiat_p256_mulx_u32(&x169, &x170, x2, (arg1[4])); + uint32_t x171; + uint32_t x172; + fiat_p256_mulx_u32(&x171, &x172, x2, (arg1[3])); + uint32_t x173; + uint32_t x174; + fiat_p256_mulx_u32(&x173, &x174, x2, (arg1[2])); + uint32_t x175; + uint32_t x176; + fiat_p256_mulx_u32(&x175, &x176, x2, (arg1[1])); + uint32_t x177; + uint32_t x178; + fiat_p256_mulx_u32(&x177, &x178, x2, (arg1[0])); + uint32_t x179; + fiat_p256_uint1 x180; + fiat_p256_addcarryx_u32(&x179, &x180, 0x0, x175, x178); + uint32_t x181; + fiat_p256_uint1 x182; + fiat_p256_addcarryx_u32(&x181, &x182, x180, x173, x176); + uint32_t x183; + fiat_p256_uint1 x184; + fiat_p256_addcarryx_u32(&x183, &x184, x182, x171, x174); + uint32_t x185; + fiat_p256_uint1 x186; + fiat_p256_addcarryx_u32(&x185, &x186, x184, x169, x172); + uint32_t x187; + fiat_p256_uint1 x188; + fiat_p256_addcarryx_u32(&x187, &x188, x186, x167, x170); + uint32_t x189; + fiat_p256_uint1 x190; + fiat_p256_addcarryx_u32(&x189, &x190, x188, x165, x168); + uint32_t x191; + fiat_p256_uint1 x192; + fiat_p256_addcarryx_u32(&x191, &x192, x190, x163, x166); + uint32_t x193; + fiat_p256_uint1 x194; + fiat_p256_addcarryx_u32(&x193, &x194, x192, 0x0, x164); + uint32_t x195; + fiat_p256_uint1 x196; + fiat_p256_addcarryx_u32(&x195, &x196, 0x0, x177, x145); + uint32_t x197; + fiat_p256_uint1 x198; + fiat_p256_addcarryx_u32(&x197, &x198, x196, x179, x147); + uint32_t x199; + fiat_p256_uint1 x200; + fiat_p256_addcarryx_u32(&x199, &x200, x198, x181, x149); + uint32_t x201; + fiat_p256_uint1 x202; + fiat_p256_addcarryx_u32(&x201, &x202, x200, x183, x151); + uint32_t x203; + fiat_p256_uint1 x204; + fiat_p256_addcarryx_u32(&x203, &x204, x202, x185, x153); + uint32_t x205; + fiat_p256_uint1 x206; + fiat_p256_addcarryx_u32(&x205, &x206, x204, x187, x155); + uint32_t x207; + fiat_p256_uint1 x208; + fiat_p256_addcarryx_u32(&x207, &x208, x206, x189, x157); + uint32_t x209; + fiat_p256_uint1 x210; + fiat_p256_addcarryx_u32(&x209, &x210, x208, x191, x159); + uint32_t x211; + fiat_p256_uint1 x212; + fiat_p256_addcarryx_u32(&x211, &x212, x210, x193, x161); + uint32_t x213; + uint32_t x214; + fiat_p256_mulx_u32(&x213, &x214, x195, UINT32_C(0xffffffff)); + uint32_t x215; + uint32_t x216; + fiat_p256_mulx_u32(&x215, &x216, x195, UINT32_C(0xffffffff)); + uint32_t x217; + uint32_t x218; + fiat_p256_mulx_u32(&x217, &x218, x195, UINT32_C(0xffffffff)); + uint32_t x219; + uint32_t x220; + fiat_p256_mulx_u32(&x219, &x220, x195, UINT32_C(0xffffffff)); + uint32_t x221; + fiat_p256_uint1 x222; + fiat_p256_addcarryx_u32(&x221, &x222, 0x0, x217, x220); + uint32_t x223; + fiat_p256_uint1 x224; + fiat_p256_addcarryx_u32(&x223, &x224, x222, x215, x218); + uint32_t x225; + fiat_p256_uint1 x226; + fiat_p256_addcarryx_u32(&x225, &x226, x224, 0x0, x216); + uint32_t x227; + fiat_p256_uint1 x228; + fiat_p256_addcarryx_u32(&x227, &x228, x226, 0x0, 0x0); + uint32_t x229; + fiat_p256_uint1 x230; + fiat_p256_addcarryx_u32(&x229, &x230, 0x0, x219, x195); + uint32_t x231; + fiat_p256_uint1 x232; + fiat_p256_addcarryx_u32(&x231, &x232, x230, x221, x197); + uint32_t x233; + fiat_p256_uint1 x234; + fiat_p256_addcarryx_u32(&x233, &x234, x232, x223, x199); + uint32_t x235; + fiat_p256_uint1 x236; + fiat_p256_addcarryx_u32(&x235, &x236, x234, x225, x201); + uint32_t x237; + fiat_p256_uint1 x238; + fiat_p256_addcarryx_u32(&x237, &x238, x236, (fiat_p256_uint1)x227, x203); + uint32_t x239; + fiat_p256_uint1 x240; + fiat_p256_addcarryx_u32(&x239, &x240, x238, 0x0, x205); + uint32_t x241; + fiat_p256_uint1 x242; + fiat_p256_addcarryx_u32(&x241, &x242, x240, x195, x207); + uint32_t x243; + fiat_p256_uint1 x244; + fiat_p256_addcarryx_u32(&x243, &x244, x242, x213, x209); + uint32_t x245; + fiat_p256_uint1 x246; + fiat_p256_addcarryx_u32(&x245, &x246, x244, x214, x211); + uint32_t x247; + fiat_p256_uint1 x248; + fiat_p256_addcarryx_u32(&x247, &x248, x246, 0x0, x212); + uint32_t x249; + uint32_t x250; + fiat_p256_mulx_u32(&x249, &x250, x3, (arg1[7])); + uint32_t x251; + uint32_t x252; + fiat_p256_mulx_u32(&x251, &x252, x3, (arg1[6])); + uint32_t x253; + uint32_t x254; + fiat_p256_mulx_u32(&x253, &x254, x3, (arg1[5])); + uint32_t x255; + uint32_t x256; + fiat_p256_mulx_u32(&x255, &x256, x3, (arg1[4])); + uint32_t x257; + uint32_t x258; + fiat_p256_mulx_u32(&x257, &x258, x3, (arg1[3])); + uint32_t x259; + uint32_t x260; + fiat_p256_mulx_u32(&x259, &x260, x3, (arg1[2])); + uint32_t x261; + uint32_t x262; + fiat_p256_mulx_u32(&x261, &x262, x3, (arg1[1])); + uint32_t x263; + uint32_t x264; + fiat_p256_mulx_u32(&x263, &x264, x3, (arg1[0])); + uint32_t x265; + fiat_p256_uint1 x266; + fiat_p256_addcarryx_u32(&x265, &x266, 0x0, x261, x264); + uint32_t x267; + fiat_p256_uint1 x268; + fiat_p256_addcarryx_u32(&x267, &x268, x266, x259, x262); + uint32_t x269; + fiat_p256_uint1 x270; + fiat_p256_addcarryx_u32(&x269, &x270, x268, x257, x260); + uint32_t x271; + fiat_p256_uint1 x272; + fiat_p256_addcarryx_u32(&x271, &x272, x270, x255, x258); + uint32_t x273; + fiat_p256_uint1 x274; + fiat_p256_addcarryx_u32(&x273, &x274, x272, x253, x256); + uint32_t x275; + fiat_p256_uint1 x276; + fiat_p256_addcarryx_u32(&x275, &x276, x274, x251, x254); + uint32_t x277; + fiat_p256_uint1 x278; + fiat_p256_addcarryx_u32(&x277, &x278, x276, x249, x252); + uint32_t x279; + fiat_p256_uint1 x280; + fiat_p256_addcarryx_u32(&x279, &x280, x278, 0x0, x250); + uint32_t x281; + fiat_p256_uint1 x282; + fiat_p256_addcarryx_u32(&x281, &x282, 0x0, x263, x231); + uint32_t x283; + fiat_p256_uint1 x284; + fiat_p256_addcarryx_u32(&x283, &x284, x282, x265, x233); + uint32_t x285; + fiat_p256_uint1 x286; + fiat_p256_addcarryx_u32(&x285, &x286, x284, x267, x235); + uint32_t x287; + fiat_p256_uint1 x288; + fiat_p256_addcarryx_u32(&x287, &x288, x286, x269, x237); + uint32_t x289; + fiat_p256_uint1 x290; + fiat_p256_addcarryx_u32(&x289, &x290, x288, x271, x239); + uint32_t x291; + fiat_p256_uint1 x292; + fiat_p256_addcarryx_u32(&x291, &x292, x290, x273, x241); + uint32_t x293; + fiat_p256_uint1 x294; + fiat_p256_addcarryx_u32(&x293, &x294, x292, x275, x243); + uint32_t x295; + fiat_p256_uint1 x296; + fiat_p256_addcarryx_u32(&x295, &x296, x294, x277, x245); + uint32_t x297; + fiat_p256_uint1 x298; + fiat_p256_addcarryx_u32(&x297, &x298, x296, x279, x247); + uint32_t x299; + uint32_t x300; + fiat_p256_mulx_u32(&x299, &x300, x281, UINT32_C(0xffffffff)); + uint32_t x301; + uint32_t x302; + fiat_p256_mulx_u32(&x301, &x302, x281, UINT32_C(0xffffffff)); + uint32_t x303; + uint32_t x304; + fiat_p256_mulx_u32(&x303, &x304, x281, UINT32_C(0xffffffff)); + uint32_t x305; + uint32_t x306; + fiat_p256_mulx_u32(&x305, &x306, x281, UINT32_C(0xffffffff)); + uint32_t x307; + fiat_p256_uint1 x308; + fiat_p256_addcarryx_u32(&x307, &x308, 0x0, x303, x306); + uint32_t x309; + fiat_p256_uint1 x310; + fiat_p256_addcarryx_u32(&x309, &x310, x308, x301, x304); + uint32_t x311; + fiat_p256_uint1 x312; + fiat_p256_addcarryx_u32(&x311, &x312, x310, 0x0, x302); + uint32_t x313; + fiat_p256_uint1 x314; + fiat_p256_addcarryx_u32(&x313, &x314, x312, 0x0, 0x0); + uint32_t x315; + fiat_p256_uint1 x316; + fiat_p256_addcarryx_u32(&x315, &x316, 0x0, x305, x281); + uint32_t x317; + fiat_p256_uint1 x318; + fiat_p256_addcarryx_u32(&x317, &x318, x316, x307, x283); + uint32_t x319; + fiat_p256_uint1 x320; + fiat_p256_addcarryx_u32(&x319, &x320, x318, x309, x285); + uint32_t x321; + fiat_p256_uint1 x322; + fiat_p256_addcarryx_u32(&x321, &x322, x320, x311, x287); + uint32_t x323; + fiat_p256_uint1 x324; + fiat_p256_addcarryx_u32(&x323, &x324, x322, (fiat_p256_uint1)x313, x289); + uint32_t x325; + fiat_p256_uint1 x326; + fiat_p256_addcarryx_u32(&x325, &x326, x324, 0x0, x291); + uint32_t x327; + fiat_p256_uint1 x328; + fiat_p256_addcarryx_u32(&x327, &x328, x326, x281, x293); + uint32_t x329; + fiat_p256_uint1 x330; + fiat_p256_addcarryx_u32(&x329, &x330, x328, x299, x295); + uint32_t x331; + fiat_p256_uint1 x332; + fiat_p256_addcarryx_u32(&x331, &x332, x330, x300, x297); + uint32_t x333; + fiat_p256_uint1 x334; + fiat_p256_addcarryx_u32(&x333, &x334, x332, 0x0, x298); + uint32_t x335; + uint32_t x336; + fiat_p256_mulx_u32(&x335, &x336, x4, (arg1[7])); + uint32_t x337; + uint32_t x338; + fiat_p256_mulx_u32(&x337, &x338, x4, (arg1[6])); + uint32_t x339; + uint32_t x340; + fiat_p256_mulx_u32(&x339, &x340, x4, (arg1[5])); + uint32_t x341; + uint32_t x342; + fiat_p256_mulx_u32(&x341, &x342, x4, (arg1[4])); + uint32_t x343; + uint32_t x344; + fiat_p256_mulx_u32(&x343, &x344, x4, (arg1[3])); + uint32_t x345; + uint32_t x346; + fiat_p256_mulx_u32(&x345, &x346, x4, (arg1[2])); + uint32_t x347; + uint32_t x348; + fiat_p256_mulx_u32(&x347, &x348, x4, (arg1[1])); + uint32_t x349; + uint32_t x350; + fiat_p256_mulx_u32(&x349, &x350, x4, (arg1[0])); + uint32_t x351; + fiat_p256_uint1 x352; + fiat_p256_addcarryx_u32(&x351, &x352, 0x0, x347, x350); + uint32_t x353; + fiat_p256_uint1 x354; + fiat_p256_addcarryx_u32(&x353, &x354, x352, x345, x348); + uint32_t x355; + fiat_p256_uint1 x356; + fiat_p256_addcarryx_u32(&x355, &x356, x354, x343, x346); + uint32_t x357; + fiat_p256_uint1 x358; + fiat_p256_addcarryx_u32(&x357, &x358, x356, x341, x344); + uint32_t x359; + fiat_p256_uint1 x360; + fiat_p256_addcarryx_u32(&x359, &x360, x358, x339, x342); + uint32_t x361; + fiat_p256_uint1 x362; + fiat_p256_addcarryx_u32(&x361, &x362, x360, x337, x340); + uint32_t x363; + fiat_p256_uint1 x364; + fiat_p256_addcarryx_u32(&x363, &x364, x362, x335, x338); + uint32_t x365; + fiat_p256_uint1 x366; + fiat_p256_addcarryx_u32(&x365, &x366, x364, 0x0, x336); + uint32_t x367; + fiat_p256_uint1 x368; + fiat_p256_addcarryx_u32(&x367, &x368, 0x0, x349, x317); + uint32_t x369; + fiat_p256_uint1 x370; + fiat_p256_addcarryx_u32(&x369, &x370, x368, x351, x319); + uint32_t x371; + fiat_p256_uint1 x372; + fiat_p256_addcarryx_u32(&x371, &x372, x370, x353, x321); + uint32_t x373; + fiat_p256_uint1 x374; + fiat_p256_addcarryx_u32(&x373, &x374, x372, x355, x323); + uint32_t x375; + fiat_p256_uint1 x376; + fiat_p256_addcarryx_u32(&x375, &x376, x374, x357, x325); + uint32_t x377; + fiat_p256_uint1 x378; + fiat_p256_addcarryx_u32(&x377, &x378, x376, x359, x327); + uint32_t x379; + fiat_p256_uint1 x380; + fiat_p256_addcarryx_u32(&x379, &x380, x378, x361, x329); + uint32_t x381; + fiat_p256_uint1 x382; + fiat_p256_addcarryx_u32(&x381, &x382, x380, x363, x331); + uint32_t x383; + fiat_p256_uint1 x384; + fiat_p256_addcarryx_u32(&x383, &x384, x382, x365, x333); + uint32_t x385; + uint32_t x386; + fiat_p256_mulx_u32(&x385, &x386, x367, UINT32_C(0xffffffff)); + uint32_t x387; + uint32_t x388; + fiat_p256_mulx_u32(&x387, &x388, x367, UINT32_C(0xffffffff)); + uint32_t x389; + uint32_t x390; + fiat_p256_mulx_u32(&x389, &x390, x367, UINT32_C(0xffffffff)); + uint32_t x391; + uint32_t x392; + fiat_p256_mulx_u32(&x391, &x392, x367, UINT32_C(0xffffffff)); + uint32_t x393; + fiat_p256_uint1 x394; + fiat_p256_addcarryx_u32(&x393, &x394, 0x0, x389, x392); + uint32_t x395; + fiat_p256_uint1 x396; + fiat_p256_addcarryx_u32(&x395, &x396, x394, x387, x390); + uint32_t x397; + fiat_p256_uint1 x398; + fiat_p256_addcarryx_u32(&x397, &x398, x396, 0x0, x388); + uint32_t x399; + fiat_p256_uint1 x400; + fiat_p256_addcarryx_u32(&x399, &x400, x398, 0x0, 0x0); + uint32_t x401; + fiat_p256_uint1 x402; + fiat_p256_addcarryx_u32(&x401, &x402, 0x0, x391, x367); + uint32_t x403; + fiat_p256_uint1 x404; + fiat_p256_addcarryx_u32(&x403, &x404, x402, x393, x369); + uint32_t x405; + fiat_p256_uint1 x406; + fiat_p256_addcarryx_u32(&x405, &x406, x404, x395, x371); + uint32_t x407; + fiat_p256_uint1 x408; + fiat_p256_addcarryx_u32(&x407, &x408, x406, x397, x373); + uint32_t x409; + fiat_p256_uint1 x410; + fiat_p256_addcarryx_u32(&x409, &x410, x408, (fiat_p256_uint1)x399, x375); + uint32_t x411; + fiat_p256_uint1 x412; + fiat_p256_addcarryx_u32(&x411, &x412, x410, 0x0, x377); + uint32_t x413; + fiat_p256_uint1 x414; + fiat_p256_addcarryx_u32(&x413, &x414, x412, x367, x379); + uint32_t x415; + fiat_p256_uint1 x416; + fiat_p256_addcarryx_u32(&x415, &x416, x414, x385, x381); + uint32_t x417; + fiat_p256_uint1 x418; + fiat_p256_addcarryx_u32(&x417, &x418, x416, x386, x383); + uint32_t x419; + fiat_p256_uint1 x420; + fiat_p256_addcarryx_u32(&x419, &x420, x418, 0x0, x384); + uint32_t x421; + uint32_t x422; + fiat_p256_mulx_u32(&x421, &x422, x5, (arg1[7])); + uint32_t x423; + uint32_t x424; + fiat_p256_mulx_u32(&x423, &x424, x5, (arg1[6])); + uint32_t x425; + uint32_t x426; + fiat_p256_mulx_u32(&x425, &x426, x5, (arg1[5])); + uint32_t x427; + uint32_t x428; + fiat_p256_mulx_u32(&x427, &x428, x5, (arg1[4])); + uint32_t x429; + uint32_t x430; + fiat_p256_mulx_u32(&x429, &x430, x5, (arg1[3])); + uint32_t x431; + uint32_t x432; + fiat_p256_mulx_u32(&x431, &x432, x5, (arg1[2])); + uint32_t x433; + uint32_t x434; + fiat_p256_mulx_u32(&x433, &x434, x5, (arg1[1])); + uint32_t x435; + uint32_t x436; + fiat_p256_mulx_u32(&x435, &x436, x5, (arg1[0])); + uint32_t x437; + fiat_p256_uint1 x438; + fiat_p256_addcarryx_u32(&x437, &x438, 0x0, x433, x436); + uint32_t x439; + fiat_p256_uint1 x440; + fiat_p256_addcarryx_u32(&x439, &x440, x438, x431, x434); + uint32_t x441; + fiat_p256_uint1 x442; + fiat_p256_addcarryx_u32(&x441, &x442, x440, x429, x432); + uint32_t x443; + fiat_p256_uint1 x444; + fiat_p256_addcarryx_u32(&x443, &x444, x442, x427, x430); + uint32_t x445; + fiat_p256_uint1 x446; + fiat_p256_addcarryx_u32(&x445, &x446, x444, x425, x428); + uint32_t x447; + fiat_p256_uint1 x448; + fiat_p256_addcarryx_u32(&x447, &x448, x446, x423, x426); + uint32_t x449; + fiat_p256_uint1 x450; + fiat_p256_addcarryx_u32(&x449, &x450, x448, x421, x424); + uint32_t x451; + fiat_p256_uint1 x452; + fiat_p256_addcarryx_u32(&x451, &x452, x450, 0x0, x422); + uint32_t x453; + fiat_p256_uint1 x454; + fiat_p256_addcarryx_u32(&x453, &x454, 0x0, x435, x403); + uint32_t x455; + fiat_p256_uint1 x456; + fiat_p256_addcarryx_u32(&x455, &x456, x454, x437, x405); + uint32_t x457; + fiat_p256_uint1 x458; + fiat_p256_addcarryx_u32(&x457, &x458, x456, x439, x407); + uint32_t x459; + fiat_p256_uint1 x460; + fiat_p256_addcarryx_u32(&x459, &x460, x458, x441, x409); + uint32_t x461; + fiat_p256_uint1 x462; + fiat_p256_addcarryx_u32(&x461, &x462, x460, x443, x411); + uint32_t x463; + fiat_p256_uint1 x464; + fiat_p256_addcarryx_u32(&x463, &x464, x462, x445, x413); + uint32_t x465; + fiat_p256_uint1 x466; + fiat_p256_addcarryx_u32(&x465, &x466, x464, x447, x415); + uint32_t x467; + fiat_p256_uint1 x468; + fiat_p256_addcarryx_u32(&x467, &x468, x466, x449, x417); + uint32_t x469; + fiat_p256_uint1 x470; + fiat_p256_addcarryx_u32(&x469, &x470, x468, x451, x419); + uint32_t x471; + uint32_t x472; + fiat_p256_mulx_u32(&x471, &x472, x453, UINT32_C(0xffffffff)); + uint32_t x473; + uint32_t x474; + fiat_p256_mulx_u32(&x473, &x474, x453, UINT32_C(0xffffffff)); + uint32_t x475; + uint32_t x476; + fiat_p256_mulx_u32(&x475, &x476, x453, UINT32_C(0xffffffff)); + uint32_t x477; + uint32_t x478; + fiat_p256_mulx_u32(&x477, &x478, x453, UINT32_C(0xffffffff)); + uint32_t x479; + fiat_p256_uint1 x480; + fiat_p256_addcarryx_u32(&x479, &x480, 0x0, x475, x478); + uint32_t x481; + fiat_p256_uint1 x482; + fiat_p256_addcarryx_u32(&x481, &x482, x480, x473, x476); + uint32_t x483; + fiat_p256_uint1 x484; + fiat_p256_addcarryx_u32(&x483, &x484, x482, 0x0, x474); + uint32_t x485; + fiat_p256_uint1 x486; + fiat_p256_addcarryx_u32(&x485, &x486, x484, 0x0, 0x0); + uint32_t x487; + fiat_p256_uint1 x488; + fiat_p256_addcarryx_u32(&x487, &x488, 0x0, x477, x453); + uint32_t x489; + fiat_p256_uint1 x490; + fiat_p256_addcarryx_u32(&x489, &x490, x488, x479, x455); + uint32_t x491; + fiat_p256_uint1 x492; + fiat_p256_addcarryx_u32(&x491, &x492, x490, x481, x457); + uint32_t x493; + fiat_p256_uint1 x494; + fiat_p256_addcarryx_u32(&x493, &x494, x492, x483, x459); + uint32_t x495; + fiat_p256_uint1 x496; + fiat_p256_addcarryx_u32(&x495, &x496, x494, (fiat_p256_uint1)x485, x461); + uint32_t x497; + fiat_p256_uint1 x498; + fiat_p256_addcarryx_u32(&x497, &x498, x496, 0x0, x463); + uint32_t x499; + fiat_p256_uint1 x500; + fiat_p256_addcarryx_u32(&x499, &x500, x498, x453, x465); + uint32_t x501; + fiat_p256_uint1 x502; + fiat_p256_addcarryx_u32(&x501, &x502, x500, x471, x467); + uint32_t x503; + fiat_p256_uint1 x504; + fiat_p256_addcarryx_u32(&x503, &x504, x502, x472, x469); + uint32_t x505; + fiat_p256_uint1 x506; + fiat_p256_addcarryx_u32(&x505, &x506, x504, 0x0, x470); + uint32_t x507; + uint32_t x508; + fiat_p256_mulx_u32(&x507, &x508, x6, (arg1[7])); + uint32_t x509; + uint32_t x510; + fiat_p256_mulx_u32(&x509, &x510, x6, (arg1[6])); + uint32_t x511; + uint32_t x512; + fiat_p256_mulx_u32(&x511, &x512, x6, (arg1[5])); + uint32_t x513; + uint32_t x514; + fiat_p256_mulx_u32(&x513, &x514, x6, (arg1[4])); + uint32_t x515; + uint32_t x516; + fiat_p256_mulx_u32(&x515, &x516, x6, (arg1[3])); + uint32_t x517; + uint32_t x518; + fiat_p256_mulx_u32(&x517, &x518, x6, (arg1[2])); + uint32_t x519; + uint32_t x520; + fiat_p256_mulx_u32(&x519, &x520, x6, (arg1[1])); + uint32_t x521; + uint32_t x522; + fiat_p256_mulx_u32(&x521, &x522, x6, (arg1[0])); + uint32_t x523; + fiat_p256_uint1 x524; + fiat_p256_addcarryx_u32(&x523, &x524, 0x0, x519, x522); + uint32_t x525; + fiat_p256_uint1 x526; + fiat_p256_addcarryx_u32(&x525, &x526, x524, x517, x520); + uint32_t x527; + fiat_p256_uint1 x528; + fiat_p256_addcarryx_u32(&x527, &x528, x526, x515, x518); + uint32_t x529; + fiat_p256_uint1 x530; + fiat_p256_addcarryx_u32(&x529, &x530, x528, x513, x516); + uint32_t x531; + fiat_p256_uint1 x532; + fiat_p256_addcarryx_u32(&x531, &x532, x530, x511, x514); + uint32_t x533; + fiat_p256_uint1 x534; + fiat_p256_addcarryx_u32(&x533, &x534, x532, x509, x512); + uint32_t x535; + fiat_p256_uint1 x536; + fiat_p256_addcarryx_u32(&x535, &x536, x534, x507, x510); + uint32_t x537; + fiat_p256_uint1 x538; + fiat_p256_addcarryx_u32(&x537, &x538, x536, 0x0, x508); + uint32_t x539; + fiat_p256_uint1 x540; + fiat_p256_addcarryx_u32(&x539, &x540, 0x0, x521, x489); + uint32_t x541; + fiat_p256_uint1 x542; + fiat_p256_addcarryx_u32(&x541, &x542, x540, x523, x491); + uint32_t x543; + fiat_p256_uint1 x544; + fiat_p256_addcarryx_u32(&x543, &x544, x542, x525, x493); + uint32_t x545; + fiat_p256_uint1 x546; + fiat_p256_addcarryx_u32(&x545, &x546, x544, x527, x495); + uint32_t x547; + fiat_p256_uint1 x548; + fiat_p256_addcarryx_u32(&x547, &x548, x546, x529, x497); + uint32_t x549; + fiat_p256_uint1 x550; + fiat_p256_addcarryx_u32(&x549, &x550, x548, x531, x499); + uint32_t x551; + fiat_p256_uint1 x552; + fiat_p256_addcarryx_u32(&x551, &x552, x550, x533, x501); + uint32_t x553; + fiat_p256_uint1 x554; + fiat_p256_addcarryx_u32(&x553, &x554, x552, x535, x503); + uint32_t x555; + fiat_p256_uint1 x556; + fiat_p256_addcarryx_u32(&x555, &x556, x554, x537, x505); + uint32_t x557; + uint32_t x558; + fiat_p256_mulx_u32(&x557, &x558, x539, UINT32_C(0xffffffff)); + uint32_t x559; + uint32_t x560; + fiat_p256_mulx_u32(&x559, &x560, x539, UINT32_C(0xffffffff)); + uint32_t x561; + uint32_t x562; + fiat_p256_mulx_u32(&x561, &x562, x539, UINT32_C(0xffffffff)); + uint32_t x563; + uint32_t x564; + fiat_p256_mulx_u32(&x563, &x564, x539, UINT32_C(0xffffffff)); + uint32_t x565; + fiat_p256_uint1 x566; + fiat_p256_addcarryx_u32(&x565, &x566, 0x0, x561, x564); + uint32_t x567; + fiat_p256_uint1 x568; + fiat_p256_addcarryx_u32(&x567, &x568, x566, x559, x562); + uint32_t x569; + fiat_p256_uint1 x570; + fiat_p256_addcarryx_u32(&x569, &x570, x568, 0x0, x560); + uint32_t x571; + fiat_p256_uint1 x572; + fiat_p256_addcarryx_u32(&x571, &x572, x570, 0x0, 0x0); + uint32_t x573; + fiat_p256_uint1 x574; + fiat_p256_addcarryx_u32(&x573, &x574, 0x0, x563, x539); + uint32_t x575; + fiat_p256_uint1 x576; + fiat_p256_addcarryx_u32(&x575, &x576, x574, x565, x541); + uint32_t x577; + fiat_p256_uint1 x578; + fiat_p256_addcarryx_u32(&x577, &x578, x576, x567, x543); + uint32_t x579; + fiat_p256_uint1 x580; + fiat_p256_addcarryx_u32(&x579, &x580, x578, x569, x545); + uint32_t x581; + fiat_p256_uint1 x582; + fiat_p256_addcarryx_u32(&x581, &x582, x580, (fiat_p256_uint1)x571, x547); + uint32_t x583; + fiat_p256_uint1 x584; + fiat_p256_addcarryx_u32(&x583, &x584, x582, 0x0, x549); + uint32_t x585; + fiat_p256_uint1 x586; + fiat_p256_addcarryx_u32(&x585, &x586, x584, x539, x551); + uint32_t x587; + fiat_p256_uint1 x588; + fiat_p256_addcarryx_u32(&x587, &x588, x586, x557, x553); + uint32_t x589; + fiat_p256_uint1 x590; + fiat_p256_addcarryx_u32(&x589, &x590, x588, x558, x555); + uint32_t x591; + fiat_p256_uint1 x592; + fiat_p256_addcarryx_u32(&x591, &x592, x590, 0x0, x556); + uint32_t x593; + uint32_t x594; + fiat_p256_mulx_u32(&x593, &x594, x7, (arg1[7])); + uint32_t x595; + uint32_t x596; + fiat_p256_mulx_u32(&x595, &x596, x7, (arg1[6])); + uint32_t x597; + uint32_t x598; + fiat_p256_mulx_u32(&x597, &x598, x7, (arg1[5])); + uint32_t x599; + uint32_t x600; + fiat_p256_mulx_u32(&x599, &x600, x7, (arg1[4])); + uint32_t x601; + uint32_t x602; + fiat_p256_mulx_u32(&x601, &x602, x7, (arg1[3])); + uint32_t x603; + uint32_t x604; + fiat_p256_mulx_u32(&x603, &x604, x7, (arg1[2])); + uint32_t x605; + uint32_t x606; + fiat_p256_mulx_u32(&x605, &x606, x7, (arg1[1])); + uint32_t x607; + uint32_t x608; + fiat_p256_mulx_u32(&x607, &x608, x7, (arg1[0])); + uint32_t x609; + fiat_p256_uint1 x610; + fiat_p256_addcarryx_u32(&x609, &x610, 0x0, x605, x608); + uint32_t x611; + fiat_p256_uint1 x612; + fiat_p256_addcarryx_u32(&x611, &x612, x610, x603, x606); + uint32_t x613; + fiat_p256_uint1 x614; + fiat_p256_addcarryx_u32(&x613, &x614, x612, x601, x604); + uint32_t x615; + fiat_p256_uint1 x616; + fiat_p256_addcarryx_u32(&x615, &x616, x614, x599, x602); + uint32_t x617; + fiat_p256_uint1 x618; + fiat_p256_addcarryx_u32(&x617, &x618, x616, x597, x600); + uint32_t x619; + fiat_p256_uint1 x620; + fiat_p256_addcarryx_u32(&x619, &x620, x618, x595, x598); + uint32_t x621; + fiat_p256_uint1 x622; + fiat_p256_addcarryx_u32(&x621, &x622, x620, x593, x596); + uint32_t x623; + fiat_p256_uint1 x624; + fiat_p256_addcarryx_u32(&x623, &x624, x622, 0x0, x594); + uint32_t x625; + fiat_p256_uint1 x626; + fiat_p256_addcarryx_u32(&x625, &x626, 0x0, x607, x575); + uint32_t x627; + fiat_p256_uint1 x628; + fiat_p256_addcarryx_u32(&x627, &x628, x626, x609, x577); + uint32_t x629; + fiat_p256_uint1 x630; + fiat_p256_addcarryx_u32(&x629, &x630, x628, x611, x579); + uint32_t x631; + fiat_p256_uint1 x632; + fiat_p256_addcarryx_u32(&x631, &x632, x630, x613, x581); + uint32_t x633; + fiat_p256_uint1 x634; + fiat_p256_addcarryx_u32(&x633, &x634, x632, x615, x583); + uint32_t x635; + fiat_p256_uint1 x636; + fiat_p256_addcarryx_u32(&x635, &x636, x634, x617, x585); + uint32_t x637; + fiat_p256_uint1 x638; + fiat_p256_addcarryx_u32(&x637, &x638, x636, x619, x587); + uint32_t x639; + fiat_p256_uint1 x640; + fiat_p256_addcarryx_u32(&x639, &x640, x638, x621, x589); + uint32_t x641; + fiat_p256_uint1 x642; + fiat_p256_addcarryx_u32(&x641, &x642, x640, x623, x591); + uint32_t x643; + uint32_t x644; + fiat_p256_mulx_u32(&x643, &x644, x625, UINT32_C(0xffffffff)); + uint32_t x645; + uint32_t x646; + fiat_p256_mulx_u32(&x645, &x646, x625, UINT32_C(0xffffffff)); + uint32_t x647; + uint32_t x648; + fiat_p256_mulx_u32(&x647, &x648, x625, UINT32_C(0xffffffff)); + uint32_t x649; + uint32_t x650; + fiat_p256_mulx_u32(&x649, &x650, x625, UINT32_C(0xffffffff)); + uint32_t x651; + fiat_p256_uint1 x652; + fiat_p256_addcarryx_u32(&x651, &x652, 0x0, x647, x650); + uint32_t x653; + fiat_p256_uint1 x654; + fiat_p256_addcarryx_u32(&x653, &x654, x652, x645, x648); + uint32_t x655; + fiat_p256_uint1 x656; + fiat_p256_addcarryx_u32(&x655, &x656, x654, 0x0, x646); + uint32_t x657; + fiat_p256_uint1 x658; + fiat_p256_addcarryx_u32(&x657, &x658, x656, 0x0, 0x0); + uint32_t x659; + fiat_p256_uint1 x660; + fiat_p256_addcarryx_u32(&x659, &x660, 0x0, x649, x625); + uint32_t x661; + fiat_p256_uint1 x662; + fiat_p256_addcarryx_u32(&x661, &x662, x660, x651, x627); + uint32_t x663; + fiat_p256_uint1 x664; + fiat_p256_addcarryx_u32(&x663, &x664, x662, x653, x629); + uint32_t x665; + fiat_p256_uint1 x666; + fiat_p256_addcarryx_u32(&x665, &x666, x664, x655, x631); + uint32_t x667; + fiat_p256_uint1 x668; + fiat_p256_addcarryx_u32(&x667, &x668, x666, (fiat_p256_uint1)x657, x633); + uint32_t x669; + fiat_p256_uint1 x670; + fiat_p256_addcarryx_u32(&x669, &x670, x668, 0x0, x635); + uint32_t x671; + fiat_p256_uint1 x672; + fiat_p256_addcarryx_u32(&x671, &x672, x670, x625, x637); + uint32_t x673; + fiat_p256_uint1 x674; + fiat_p256_addcarryx_u32(&x673, &x674, x672, x643, x639); + uint32_t x675; + fiat_p256_uint1 x676; + fiat_p256_addcarryx_u32(&x675, &x676, x674, x644, x641); + uint32_t x677; + fiat_p256_uint1 x678; + fiat_p256_addcarryx_u32(&x677, &x678, x676, 0x0, x642); + uint32_t x679; + fiat_p256_uint1 x680; + fiat_p256_subborrowx_u32(&x679, &x680, 0x0, x661, UINT32_C(0xffffffff)); + uint32_t x681; + fiat_p256_uint1 x682; + fiat_p256_subborrowx_u32(&x681, &x682, x680, x663, UINT32_C(0xffffffff)); + uint32_t x683; + fiat_p256_uint1 x684; + fiat_p256_subborrowx_u32(&x683, &x684, x682, x665, UINT32_C(0xffffffff)); + uint32_t x685; + fiat_p256_uint1 x686; + fiat_p256_subborrowx_u32(&x685, &x686, x684, x667, 0x0); + uint32_t x687; + fiat_p256_uint1 x688; + fiat_p256_subborrowx_u32(&x687, &x688, x686, x669, 0x0); + uint32_t x689; + fiat_p256_uint1 x690; + fiat_p256_subborrowx_u32(&x689, &x690, x688, x671, 0x0); + uint32_t x691; + fiat_p256_uint1 x692; + fiat_p256_subborrowx_u32(&x691, &x692, x690, x673, 0x1); + uint32_t x693; + fiat_p256_uint1 x694; + fiat_p256_subborrowx_u32(&x693, &x694, x692, x675, UINT32_C(0xffffffff)); + uint32_t x695; + fiat_p256_uint1 x696; + fiat_p256_subborrowx_u32(&x695, &x696, x694, x677, 0x0); + uint32_t x697; + fiat_p256_cmovznz_u32(&x697, x696, x679, x661); + uint32_t x698; + fiat_p256_cmovznz_u32(&x698, x696, x681, x663); + uint32_t x699; + fiat_p256_cmovznz_u32(&x699, x696, x683, x665); + uint32_t x700; + fiat_p256_cmovznz_u32(&x700, x696, x685, x667); + uint32_t x701; + fiat_p256_cmovznz_u32(&x701, x696, x687, x669); + uint32_t x702; + fiat_p256_cmovznz_u32(&x702, x696, x689, x671); + uint32_t x703; + fiat_p256_cmovznz_u32(&x703, x696, x691, x673); + uint32_t x704; + fiat_p256_cmovznz_u32(&x704, x696, x693, x675); + out1[0] = x697; + out1[1] = x698; + out1[2] = x699; + out1[3] = x700; + out1[4] = x701; + out1[5] = x702; + out1[6] = x703; + out1[7] = x704; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_add(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_addcarryx_u32(&x1, &x2, 0x0, (arg2[0]), (arg1[0])); + uint32_t x3; + fiat_p256_uint1 x4; + fiat_p256_addcarryx_u32(&x3, &x4, x2, (arg2[1]), (arg1[1])); + uint32_t x5; + fiat_p256_uint1 x6; + fiat_p256_addcarryx_u32(&x5, &x6, x4, (arg2[2]), (arg1[2])); + uint32_t x7; + fiat_p256_uint1 x8; + fiat_p256_addcarryx_u32(&x7, &x8, x6, (arg2[3]), (arg1[3])); + uint32_t x9; + fiat_p256_uint1 x10; + fiat_p256_addcarryx_u32(&x9, &x10, x8, (arg2[4]), (arg1[4])); + uint32_t x11; + fiat_p256_uint1 x12; + fiat_p256_addcarryx_u32(&x11, &x12, x10, (arg2[5]), (arg1[5])); + uint32_t x13; + fiat_p256_uint1 x14; + fiat_p256_addcarryx_u32(&x13, &x14, x12, (arg2[6]), (arg1[6])); + uint32_t x15; + fiat_p256_uint1 x16; + fiat_p256_addcarryx_u32(&x15, &x16, x14, (arg2[7]), (arg1[7])); + uint32_t x17; + fiat_p256_uint1 x18; + fiat_p256_subborrowx_u32(&x17, &x18, 0x0, x1, UINT32_C(0xffffffff)); + uint32_t x19; + fiat_p256_uint1 x20; + fiat_p256_subborrowx_u32(&x19, &x20, x18, x3, UINT32_C(0xffffffff)); + uint32_t x21; + fiat_p256_uint1 x22; + fiat_p256_subborrowx_u32(&x21, &x22, x20, x5, UINT32_C(0xffffffff)); + uint32_t x23; + fiat_p256_uint1 x24; + fiat_p256_subborrowx_u32(&x23, &x24, x22, x7, 0x0); + uint32_t x25; + fiat_p256_uint1 x26; + fiat_p256_subborrowx_u32(&x25, &x26, x24, x9, 0x0); + uint32_t x27; + fiat_p256_uint1 x28; + fiat_p256_subborrowx_u32(&x27, &x28, x26, x11, 0x0); + uint32_t x29; + fiat_p256_uint1 x30; + fiat_p256_subborrowx_u32(&x29, &x30, x28, x13, 0x1); + uint32_t x31; + fiat_p256_uint1 x32; + fiat_p256_subborrowx_u32(&x31, &x32, x30, x15, UINT32_C(0xffffffff)); + uint32_t x33; + fiat_p256_uint1 x34; + fiat_p256_subborrowx_u32(&x33, &x34, x32, x16, 0x0); + uint32_t x35; + fiat_p256_cmovznz_u32(&x35, x34, x17, x1); + uint32_t x36; + fiat_p256_cmovznz_u32(&x36, x34, x19, x3); + uint32_t x37; + fiat_p256_cmovznz_u32(&x37, x34, x21, x5); + uint32_t x38; + fiat_p256_cmovznz_u32(&x38, x34, x23, x7); + uint32_t x39; + fiat_p256_cmovznz_u32(&x39, x34, x25, x9); + uint32_t x40; + fiat_p256_cmovznz_u32(&x40, x34, x27, x11); + uint32_t x41; + fiat_p256_cmovznz_u32(&x41, x34, x29, x13); + uint32_t x42; + fiat_p256_cmovznz_u32(&x42, x34, x31, x15); + out1[0] = x35; + out1[1] = x36; + out1[2] = x37; + out1[3] = x38; + out1[4] = x39; + out1[5] = x40; + out1[6] = x41; + out1[7] = x42; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_sub(uint32_t out1[8], const uint32_t arg1[8], const uint32_t arg2[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + uint32_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u32(&x3, &x4, x2, (arg1[1]), (arg2[1])); + uint32_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u32(&x5, &x6, x4, (arg1[2]), (arg2[2])); + uint32_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u32(&x7, &x8, x6, (arg1[3]), (arg2[3])); + uint32_t x9; + fiat_p256_uint1 x10; + fiat_p256_subborrowx_u32(&x9, &x10, x8, (arg1[4]), (arg2[4])); + uint32_t x11; + fiat_p256_uint1 x12; + fiat_p256_subborrowx_u32(&x11, &x12, x10, (arg1[5]), (arg2[5])); + uint32_t x13; + fiat_p256_uint1 x14; + fiat_p256_subborrowx_u32(&x13, &x14, x12, (arg1[6]), (arg2[6])); + uint32_t x15; + fiat_p256_uint1 x16; + fiat_p256_subborrowx_u32(&x15, &x16, x14, (arg1[7]), (arg2[7])); + uint32_t x17; + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + uint32_t x18; + fiat_p256_uint1 x19; + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, (x17 & UINT32_C(0xffffffff)), x1); + uint32_t x20; + fiat_p256_uint1 x21; + fiat_p256_addcarryx_u32(&x20, &x21, x19, (x17 & UINT32_C(0xffffffff)), x3); + uint32_t x22; + fiat_p256_uint1 x23; + fiat_p256_addcarryx_u32(&x22, &x23, x21, (x17 & UINT32_C(0xffffffff)), x5); + uint32_t x24; + fiat_p256_uint1 x25; + fiat_p256_addcarryx_u32(&x24, &x25, x23, 0x0, x7); + uint32_t x26; + fiat_p256_uint1 x27; + fiat_p256_addcarryx_u32(&x26, &x27, x25, 0x0, x9); + uint32_t x28; + fiat_p256_uint1 x29; + fiat_p256_addcarryx_u32(&x28, &x29, x27, 0x0, x11); + uint32_t x30; + fiat_p256_uint1 x31; + fiat_p256_addcarryx_u32(&x30, &x31, x29, (fiat_p256_uint1)(x17 & 0x1), x13); + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_addcarryx_u32(&x32, &x33, x31, (x17 & UINT32_C(0xffffffff)), x15); + out1[0] = x18; + out1[1] = x20; + out1[2] = x22; + out1[3] = x24; + out1[4] = x26; + out1[5] = x28; + out1[6] = x30; + out1[7] = x32; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_opp(uint32_t out1[8], const uint32_t arg1[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, 0x0, (arg1[0])); + uint32_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u32(&x3, &x4, x2, 0x0, (arg1[1])); + uint32_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u32(&x5, &x6, x4, 0x0, (arg1[2])); + uint32_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u32(&x7, &x8, x6, 0x0, (arg1[3])); + uint32_t x9; + fiat_p256_uint1 x10; + fiat_p256_subborrowx_u32(&x9, &x10, x8, 0x0, (arg1[4])); + uint32_t x11; + fiat_p256_uint1 x12; + fiat_p256_subborrowx_u32(&x11, &x12, x10, 0x0, (arg1[5])); + uint32_t x13; + fiat_p256_uint1 x14; + fiat_p256_subborrowx_u32(&x13, &x14, x12, 0x0, (arg1[6])); + uint32_t x15; + fiat_p256_uint1 x16; + fiat_p256_subborrowx_u32(&x15, &x16, x14, 0x0, (arg1[7])); + uint32_t x17; + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + uint32_t x18; + fiat_p256_uint1 x19; + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, (x17 & UINT32_C(0xffffffff)), x1); + uint32_t x20; + fiat_p256_uint1 x21; + fiat_p256_addcarryx_u32(&x20, &x21, x19, (x17 & UINT32_C(0xffffffff)), x3); + uint32_t x22; + fiat_p256_uint1 x23; + fiat_p256_addcarryx_u32(&x22, &x23, x21, (x17 & UINT32_C(0xffffffff)), x5); + uint32_t x24; + fiat_p256_uint1 x25; + fiat_p256_addcarryx_u32(&x24, &x25, x23, 0x0, x7); + uint32_t x26; + fiat_p256_uint1 x27; + fiat_p256_addcarryx_u32(&x26, &x27, x25, 0x0, x9); + uint32_t x28; + fiat_p256_uint1 x29; + fiat_p256_addcarryx_u32(&x28, &x29, x27, 0x0, x11); + uint32_t x30; + fiat_p256_uint1 x31; + fiat_p256_addcarryx_u32(&x30, &x31, x29, (fiat_p256_uint1)(x17 & 0x1), x13); + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_addcarryx_u32(&x32, &x33, x31, (x17 & UINT32_C(0xffffffff)), x15); + out1[0] = x18; + out1[1] = x20; + out1[2] = x22; + out1[3] = x24; + out1[4] = x26; + out1[5] = x28; + out1[6] = x30; + out1[7] = x32; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_from_montgomery(uint32_t out1[8], const uint32_t arg1[8]) { + uint32_t x1 = (arg1[0]); + uint32_t x2; + uint32_t x3; + fiat_p256_mulx_u32(&x2, &x3, x1, UINT32_C(0xffffffff)); + uint32_t x4; + uint32_t x5; + fiat_p256_mulx_u32(&x4, &x5, x1, UINT32_C(0xffffffff)); + uint32_t x6; + uint32_t x7; + fiat_p256_mulx_u32(&x6, &x7, x1, UINT32_C(0xffffffff)); + uint32_t x8; + uint32_t x9; + fiat_p256_mulx_u32(&x8, &x9, x1, UINT32_C(0xffffffff)); + uint32_t x10; + fiat_p256_uint1 x11; + fiat_p256_addcarryx_u32(&x10, &x11, 0x0, x6, x9); + uint32_t x12; + fiat_p256_uint1 x13; + fiat_p256_addcarryx_u32(&x12, &x13, x11, x4, x7); + uint32_t x14; + fiat_p256_uint1 x15; + fiat_p256_addcarryx_u32(&x14, &x15, x13, 0x0, x5); + uint32_t x16; + fiat_p256_uint1 x17; + fiat_p256_addcarryx_u32(&x16, &x17, 0x0, x8, x1); + uint32_t x18; + fiat_p256_uint1 x19; + fiat_p256_addcarryx_u32(&x18, &x19, x17, x10, 0x0); + uint32_t x20; + fiat_p256_uint1 x21; + fiat_p256_addcarryx_u32(&x20, &x21, x19, x12, 0x0); + uint32_t x22; + fiat_p256_uint1 x23; + fiat_p256_addcarryx_u32(&x22, &x23, x21, x14, 0x0); + uint32_t x24; + fiat_p256_uint1 x25; + fiat_p256_addcarryx_u32(&x24, &x25, x15, 0x0, 0x0); + uint32_t x26; + fiat_p256_uint1 x27; + fiat_p256_addcarryx_u32(&x26, &x27, x23, (fiat_p256_uint1)x24, 0x0); + uint32_t x28; + fiat_p256_uint1 x29; + fiat_p256_addcarryx_u32(&x28, &x29, 0x0, (arg1[1]), x18); + uint32_t x30; + fiat_p256_uint1 x31; + fiat_p256_addcarryx_u32(&x30, &x31, x29, 0x0, x20); + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_addcarryx_u32(&x32, &x33, x31, 0x0, x22); + uint32_t x34; + fiat_p256_uint1 x35; + fiat_p256_addcarryx_u32(&x34, &x35, x33, 0x0, (fiat_p256_uint1)x26); + uint32_t x36; + fiat_p256_uint1 x37; + fiat_p256_addcarryx_u32(&x36, &x37, x27, 0x0, 0x0); + uint32_t x38; + fiat_p256_uint1 x39; + fiat_p256_addcarryx_u32(&x38, &x39, x35, 0x0, (fiat_p256_uint1)x36); + uint32_t x40; + fiat_p256_uint1 x41; + fiat_p256_addcarryx_u32(&x40, &x41, x39, 0x0, x1); + uint32_t x42; + fiat_p256_uint1 x43; + fiat_p256_addcarryx_u32(&x42, &x43, x41, 0x0, x2); + uint32_t x44; + fiat_p256_uint1 x45; + fiat_p256_addcarryx_u32(&x44, &x45, x43, 0x0, x3); + uint32_t x46; + uint32_t x47; + fiat_p256_mulx_u32(&x46, &x47, x28, UINT32_C(0xffffffff)); + uint32_t x48; + uint32_t x49; + fiat_p256_mulx_u32(&x48, &x49, x28, UINT32_C(0xffffffff)); + uint32_t x50; + uint32_t x51; + fiat_p256_mulx_u32(&x50, &x51, x28, UINT32_C(0xffffffff)); + uint32_t x52; + uint32_t x53; + fiat_p256_mulx_u32(&x52, &x53, x28, UINT32_C(0xffffffff)); + uint32_t x54; + fiat_p256_uint1 x55; + fiat_p256_addcarryx_u32(&x54, &x55, 0x0, x50, x53); + uint32_t x56; + fiat_p256_uint1 x57; + fiat_p256_addcarryx_u32(&x56, &x57, x55, x48, x51); + uint32_t x58; + fiat_p256_uint1 x59; + fiat_p256_addcarryx_u32(&x58, &x59, x57, 0x0, x49); + uint32_t x60; + fiat_p256_uint1 x61; + fiat_p256_addcarryx_u32(&x60, &x61, 0x0, x52, x28); + uint32_t x62; + fiat_p256_uint1 x63; + fiat_p256_addcarryx_u32(&x62, &x63, x61, x54, x30); + uint32_t x64; + fiat_p256_uint1 x65; + fiat_p256_addcarryx_u32(&x64, &x65, x63, x56, x32); + uint32_t x66; + fiat_p256_uint1 x67; + fiat_p256_addcarryx_u32(&x66, &x67, x65, x58, x34); + uint32_t x68; + fiat_p256_uint1 x69; + fiat_p256_addcarryx_u32(&x68, &x69, x59, 0x0, 0x0); + uint32_t x70; + fiat_p256_uint1 x71; + fiat_p256_addcarryx_u32(&x70, &x71, x67, (fiat_p256_uint1)x68, (fiat_p256_uint1)x38); + uint32_t x72; + fiat_p256_uint1 x73; + fiat_p256_addcarryx_u32(&x72, &x73, x71, 0x0, x40); + uint32_t x74; + fiat_p256_uint1 x75; + fiat_p256_addcarryx_u32(&x74, &x75, x73, x28, x42); + uint32_t x76; + fiat_p256_uint1 x77; + fiat_p256_addcarryx_u32(&x76, &x77, x75, x46, x44); + uint32_t x78; + fiat_p256_uint1 x79; + fiat_p256_addcarryx_u32(&x78, &x79, x45, 0x0, 0x0); + uint32_t x80; + fiat_p256_uint1 x81; + fiat_p256_addcarryx_u32(&x80, &x81, x77, x47, (fiat_p256_uint1)x78); + uint32_t x82; + fiat_p256_uint1 x83; + fiat_p256_addcarryx_u32(&x82, &x83, 0x0, (arg1[2]), x62); + uint32_t x84; + fiat_p256_uint1 x85; + fiat_p256_addcarryx_u32(&x84, &x85, x83, 0x0, x64); + uint32_t x86; + fiat_p256_uint1 x87; + fiat_p256_addcarryx_u32(&x86, &x87, x85, 0x0, x66); + uint32_t x88; + fiat_p256_uint1 x89; + fiat_p256_addcarryx_u32(&x88, &x89, x87, 0x0, (fiat_p256_uint1)x70); + uint32_t x90; + fiat_p256_uint1 x91; + fiat_p256_addcarryx_u32(&x90, &x91, x89, 0x0, x72); + uint32_t x92; + fiat_p256_uint1 x93; + fiat_p256_addcarryx_u32(&x92, &x93, x91, 0x0, x74); + uint32_t x94; + fiat_p256_uint1 x95; + fiat_p256_addcarryx_u32(&x94, &x95, x93, 0x0, x76); + uint32_t x96; + fiat_p256_uint1 x97; + fiat_p256_addcarryx_u32(&x96, &x97, x95, 0x0, x80); + uint32_t x98; + fiat_p256_uint1 x99; + fiat_p256_addcarryx_u32(&x98, &x99, x81, 0x0, 0x0); + uint32_t x100; + fiat_p256_uint1 x101; + fiat_p256_addcarryx_u32(&x100, &x101, x97, 0x0, (fiat_p256_uint1)x98); + uint32_t x102; + uint32_t x103; + fiat_p256_mulx_u32(&x102, &x103, x82, UINT32_C(0xffffffff)); + uint32_t x104; + uint32_t x105; + fiat_p256_mulx_u32(&x104, &x105, x82, UINT32_C(0xffffffff)); + uint32_t x106; + uint32_t x107; + fiat_p256_mulx_u32(&x106, &x107, x82, UINT32_C(0xffffffff)); + uint32_t x108; + uint32_t x109; + fiat_p256_mulx_u32(&x108, &x109, x82, UINT32_C(0xffffffff)); + uint32_t x110; + fiat_p256_uint1 x111; + fiat_p256_addcarryx_u32(&x110, &x111, 0x0, x106, x109); + uint32_t x112; + fiat_p256_uint1 x113; + fiat_p256_addcarryx_u32(&x112, &x113, x111, x104, x107); + uint32_t x114; + fiat_p256_uint1 x115; + fiat_p256_addcarryx_u32(&x114, &x115, x113, 0x0, x105); + uint32_t x116; + fiat_p256_uint1 x117; + fiat_p256_addcarryx_u32(&x116, &x117, 0x0, x108, x82); + uint32_t x118; + fiat_p256_uint1 x119; + fiat_p256_addcarryx_u32(&x118, &x119, x117, x110, x84); + uint32_t x120; + fiat_p256_uint1 x121; + fiat_p256_addcarryx_u32(&x120, &x121, x119, x112, x86); + uint32_t x122; + fiat_p256_uint1 x123; + fiat_p256_addcarryx_u32(&x122, &x123, x121, x114, x88); + uint32_t x124; + fiat_p256_uint1 x125; + fiat_p256_addcarryx_u32(&x124, &x125, x115, 0x0, 0x0); + uint32_t x126; + fiat_p256_uint1 x127; + fiat_p256_addcarryx_u32(&x126, &x127, x123, (fiat_p256_uint1)x124, x90); + uint32_t x128; + fiat_p256_uint1 x129; + fiat_p256_addcarryx_u32(&x128, &x129, x127, 0x0, x92); + uint32_t x130; + fiat_p256_uint1 x131; + fiat_p256_addcarryx_u32(&x130, &x131, x129, x82, x94); + uint32_t x132; + fiat_p256_uint1 x133; + fiat_p256_addcarryx_u32(&x132, &x133, x131, x102, x96); + uint32_t x134; + fiat_p256_uint1 x135; + fiat_p256_addcarryx_u32(&x134, &x135, x133, x103, (fiat_p256_uint1)x100); + uint32_t x136; + fiat_p256_uint1 x137; + fiat_p256_addcarryx_u32(&x136, &x137, 0x0, (arg1[3]), x118); + uint32_t x138; + fiat_p256_uint1 x139; + fiat_p256_addcarryx_u32(&x138, &x139, x137, 0x0, x120); + uint32_t x140; + fiat_p256_uint1 x141; + fiat_p256_addcarryx_u32(&x140, &x141, x139, 0x0, x122); + uint32_t x142; + fiat_p256_uint1 x143; + fiat_p256_addcarryx_u32(&x142, &x143, x141, 0x0, x126); + uint32_t x144; + fiat_p256_uint1 x145; + fiat_p256_addcarryx_u32(&x144, &x145, x143, 0x0, x128); + uint32_t x146; + fiat_p256_uint1 x147; + fiat_p256_addcarryx_u32(&x146, &x147, x145, 0x0, x130); + uint32_t x148; + fiat_p256_uint1 x149; + fiat_p256_addcarryx_u32(&x148, &x149, x147, 0x0, x132); + uint32_t x150; + fiat_p256_uint1 x151; + fiat_p256_addcarryx_u32(&x150, &x151, x149, 0x0, x134); + uint32_t x152; + fiat_p256_uint1 x153; + fiat_p256_addcarryx_u32(&x152, &x153, x135, 0x0, x101); + uint32_t x154; + fiat_p256_uint1 x155; + fiat_p256_addcarryx_u32(&x154, &x155, x151, 0x0, (fiat_p256_uint1)x152); + uint32_t x156; + uint32_t x157; + fiat_p256_mulx_u32(&x156, &x157, x136, UINT32_C(0xffffffff)); + uint32_t x158; + uint32_t x159; + fiat_p256_mulx_u32(&x158, &x159, x136, UINT32_C(0xffffffff)); + uint32_t x160; + uint32_t x161; + fiat_p256_mulx_u32(&x160, &x161, x136, UINT32_C(0xffffffff)); + uint32_t x162; + uint32_t x163; + fiat_p256_mulx_u32(&x162, &x163, x136, UINT32_C(0xffffffff)); + uint32_t x164; + fiat_p256_uint1 x165; + fiat_p256_addcarryx_u32(&x164, &x165, 0x0, x160, x163); + uint32_t x166; + fiat_p256_uint1 x167; + fiat_p256_addcarryx_u32(&x166, &x167, x165, x158, x161); + uint32_t x168; + fiat_p256_uint1 x169; + fiat_p256_addcarryx_u32(&x168, &x169, x167, 0x0, x159); + uint32_t x170; + fiat_p256_uint1 x171; + fiat_p256_addcarryx_u32(&x170, &x171, 0x0, x162, x136); + uint32_t x172; + fiat_p256_uint1 x173; + fiat_p256_addcarryx_u32(&x172, &x173, x171, x164, x138); + uint32_t x174; + fiat_p256_uint1 x175; + fiat_p256_addcarryx_u32(&x174, &x175, x173, x166, x140); + uint32_t x176; + fiat_p256_uint1 x177; + fiat_p256_addcarryx_u32(&x176, &x177, x175, x168, x142); + uint32_t x178; + fiat_p256_uint1 x179; + fiat_p256_addcarryx_u32(&x178, &x179, x169, 0x0, 0x0); + uint32_t x180; + fiat_p256_uint1 x181; + fiat_p256_addcarryx_u32(&x180, &x181, x177, (fiat_p256_uint1)x178, x144); + uint32_t x182; + fiat_p256_uint1 x183; + fiat_p256_addcarryx_u32(&x182, &x183, x181, 0x0, x146); + uint32_t x184; + fiat_p256_uint1 x185; + fiat_p256_addcarryx_u32(&x184, &x185, x183, x136, x148); + uint32_t x186; + fiat_p256_uint1 x187; + fiat_p256_addcarryx_u32(&x186, &x187, x185, x156, x150); + uint32_t x188; + fiat_p256_uint1 x189; + fiat_p256_addcarryx_u32(&x188, &x189, x187, x157, (fiat_p256_uint1)x154); + uint32_t x190; + fiat_p256_uint1 x191; + fiat_p256_addcarryx_u32(&x190, &x191, 0x0, (arg1[4]), x172); + uint32_t x192; + fiat_p256_uint1 x193; + fiat_p256_addcarryx_u32(&x192, &x193, x191, 0x0, x174); + uint32_t x194; + fiat_p256_uint1 x195; + fiat_p256_addcarryx_u32(&x194, &x195, x193, 0x0, x176); + uint32_t x196; + fiat_p256_uint1 x197; + fiat_p256_addcarryx_u32(&x196, &x197, x195, 0x0, x180); + uint32_t x198; + fiat_p256_uint1 x199; + fiat_p256_addcarryx_u32(&x198, &x199, x197, 0x0, x182); + uint32_t x200; + fiat_p256_uint1 x201; + fiat_p256_addcarryx_u32(&x200, &x201, x199, 0x0, x184); + uint32_t x202; + fiat_p256_uint1 x203; + fiat_p256_addcarryx_u32(&x202, &x203, x201, 0x0, x186); + uint32_t x204; + fiat_p256_uint1 x205; + fiat_p256_addcarryx_u32(&x204, &x205, x203, 0x0, x188); + uint32_t x206; + fiat_p256_uint1 x207; + fiat_p256_addcarryx_u32(&x206, &x207, x189, 0x0, x155); + uint32_t x208; + fiat_p256_uint1 x209; + fiat_p256_addcarryx_u32(&x208, &x209, x205, 0x0, (fiat_p256_uint1)x206); + uint32_t x210; + uint32_t x211; + fiat_p256_mulx_u32(&x210, &x211, x190, UINT32_C(0xffffffff)); + uint32_t x212; + uint32_t x213; + fiat_p256_mulx_u32(&x212, &x213, x190, UINT32_C(0xffffffff)); + uint32_t x214; + uint32_t x215; + fiat_p256_mulx_u32(&x214, &x215, x190, UINT32_C(0xffffffff)); + uint32_t x216; + uint32_t x217; + fiat_p256_mulx_u32(&x216, &x217, x190, UINT32_C(0xffffffff)); + uint32_t x218; + fiat_p256_uint1 x219; + fiat_p256_addcarryx_u32(&x218, &x219, 0x0, x214, x217); + uint32_t x220; + fiat_p256_uint1 x221; + fiat_p256_addcarryx_u32(&x220, &x221, x219, x212, x215); + uint32_t x222; + fiat_p256_uint1 x223; + fiat_p256_addcarryx_u32(&x222, &x223, x221, 0x0, x213); + uint32_t x224; + fiat_p256_uint1 x225; + fiat_p256_addcarryx_u32(&x224, &x225, 0x0, x216, x190); + uint32_t x226; + fiat_p256_uint1 x227; + fiat_p256_addcarryx_u32(&x226, &x227, x225, x218, x192); + uint32_t x228; + fiat_p256_uint1 x229; + fiat_p256_addcarryx_u32(&x228, &x229, x227, x220, x194); + uint32_t x230; + fiat_p256_uint1 x231; + fiat_p256_addcarryx_u32(&x230, &x231, x229, x222, x196); + uint32_t x232; + fiat_p256_uint1 x233; + fiat_p256_addcarryx_u32(&x232, &x233, x223, 0x0, 0x0); + uint32_t x234; + fiat_p256_uint1 x235; + fiat_p256_addcarryx_u32(&x234, &x235, x231, (fiat_p256_uint1)x232, x198); + uint32_t x236; + fiat_p256_uint1 x237; + fiat_p256_addcarryx_u32(&x236, &x237, x235, 0x0, x200); + uint32_t x238; + fiat_p256_uint1 x239; + fiat_p256_addcarryx_u32(&x238, &x239, x237, x190, x202); + uint32_t x240; + fiat_p256_uint1 x241; + fiat_p256_addcarryx_u32(&x240, &x241, x239, x210, x204); + uint32_t x242; + fiat_p256_uint1 x243; + fiat_p256_addcarryx_u32(&x242, &x243, x241, x211, x208); + uint32_t x244; + fiat_p256_uint1 x245; + fiat_p256_addcarryx_u32(&x244, &x245, 0x0, (arg1[5]), x226); + uint32_t x246; + fiat_p256_uint1 x247; + fiat_p256_addcarryx_u32(&x246, &x247, x245, 0x0, x228); + uint32_t x248; + fiat_p256_uint1 x249; + fiat_p256_addcarryx_u32(&x248, &x249, x247, 0x0, x230); + uint32_t x250; + fiat_p256_uint1 x251; + fiat_p256_addcarryx_u32(&x250, &x251, x249, 0x0, x234); + uint32_t x252; + fiat_p256_uint1 x253; + fiat_p256_addcarryx_u32(&x252, &x253, x251, 0x0, x236); + uint32_t x254; + fiat_p256_uint1 x255; + fiat_p256_addcarryx_u32(&x254, &x255, x253, 0x0, x238); + uint32_t x256; + fiat_p256_uint1 x257; + fiat_p256_addcarryx_u32(&x256, &x257, x255, 0x0, x240); + uint32_t x258; + fiat_p256_uint1 x259; + fiat_p256_addcarryx_u32(&x258, &x259, x257, 0x0, x242); + uint32_t x260; + fiat_p256_uint1 x261; + fiat_p256_addcarryx_u32(&x260, &x261, x243, 0x0, x209); + uint32_t x262; + fiat_p256_uint1 x263; + fiat_p256_addcarryx_u32(&x262, &x263, x259, 0x0, (fiat_p256_uint1)x260); + uint32_t x264; + uint32_t x265; + fiat_p256_mulx_u32(&x264, &x265, x244, UINT32_C(0xffffffff)); + uint32_t x266; + uint32_t x267; + fiat_p256_mulx_u32(&x266, &x267, x244, UINT32_C(0xffffffff)); + uint32_t x268; + uint32_t x269; + fiat_p256_mulx_u32(&x268, &x269, x244, UINT32_C(0xffffffff)); + uint32_t x270; + uint32_t x271; + fiat_p256_mulx_u32(&x270, &x271, x244, UINT32_C(0xffffffff)); + uint32_t x272; + fiat_p256_uint1 x273; + fiat_p256_addcarryx_u32(&x272, &x273, 0x0, x268, x271); + uint32_t x274; + fiat_p256_uint1 x275; + fiat_p256_addcarryx_u32(&x274, &x275, x273, x266, x269); + uint32_t x276; + fiat_p256_uint1 x277; + fiat_p256_addcarryx_u32(&x276, &x277, x275, 0x0, x267); + uint32_t x278; + fiat_p256_uint1 x279; + fiat_p256_addcarryx_u32(&x278, &x279, 0x0, x270, x244); + uint32_t x280; + fiat_p256_uint1 x281; + fiat_p256_addcarryx_u32(&x280, &x281, x279, x272, x246); + uint32_t x282; + fiat_p256_uint1 x283; + fiat_p256_addcarryx_u32(&x282, &x283, x281, x274, x248); + uint32_t x284; + fiat_p256_uint1 x285; + fiat_p256_addcarryx_u32(&x284, &x285, x283, x276, x250); + uint32_t x286; + fiat_p256_uint1 x287; + fiat_p256_addcarryx_u32(&x286, &x287, x277, 0x0, 0x0); + uint32_t x288; + fiat_p256_uint1 x289; + fiat_p256_addcarryx_u32(&x288, &x289, x285, (fiat_p256_uint1)x286, x252); + uint32_t x290; + fiat_p256_uint1 x291; + fiat_p256_addcarryx_u32(&x290, &x291, x289, 0x0, x254); + uint32_t x292; + fiat_p256_uint1 x293; + fiat_p256_addcarryx_u32(&x292, &x293, x291, x244, x256); + uint32_t x294; + fiat_p256_uint1 x295; + fiat_p256_addcarryx_u32(&x294, &x295, x293, x264, x258); + uint32_t x296; + fiat_p256_uint1 x297; + fiat_p256_addcarryx_u32(&x296, &x297, x295, x265, x262); + uint32_t x298; + fiat_p256_uint1 x299; + fiat_p256_addcarryx_u32(&x298, &x299, 0x0, (arg1[6]), x280); + uint32_t x300; + fiat_p256_uint1 x301; + fiat_p256_addcarryx_u32(&x300, &x301, x299, 0x0, x282); + uint32_t x302; + fiat_p256_uint1 x303; + fiat_p256_addcarryx_u32(&x302, &x303, x301, 0x0, x284); + uint32_t x304; + fiat_p256_uint1 x305; + fiat_p256_addcarryx_u32(&x304, &x305, x303, 0x0, x288); + uint32_t x306; + fiat_p256_uint1 x307; + fiat_p256_addcarryx_u32(&x306, &x307, x305, 0x0, x290); + uint32_t x308; + fiat_p256_uint1 x309; + fiat_p256_addcarryx_u32(&x308, &x309, x307, 0x0, x292); + uint32_t x310; + fiat_p256_uint1 x311; + fiat_p256_addcarryx_u32(&x310, &x311, x309, 0x0, x294); + uint32_t x312; + fiat_p256_uint1 x313; + fiat_p256_addcarryx_u32(&x312, &x313, x311, 0x0, x296); + uint32_t x314; + fiat_p256_uint1 x315; + fiat_p256_addcarryx_u32(&x314, &x315, x297, 0x0, x263); + uint32_t x316; + fiat_p256_uint1 x317; + fiat_p256_addcarryx_u32(&x316, &x317, x313, 0x0, (fiat_p256_uint1)x314); + uint32_t x318; + uint32_t x319; + fiat_p256_mulx_u32(&x318, &x319, x298, UINT32_C(0xffffffff)); + uint32_t x320; + uint32_t x321; + fiat_p256_mulx_u32(&x320, &x321, x298, UINT32_C(0xffffffff)); + uint32_t x322; + uint32_t x323; + fiat_p256_mulx_u32(&x322, &x323, x298, UINT32_C(0xffffffff)); + uint32_t x324; + uint32_t x325; + fiat_p256_mulx_u32(&x324, &x325, x298, UINT32_C(0xffffffff)); + uint32_t x326; + fiat_p256_uint1 x327; + fiat_p256_addcarryx_u32(&x326, &x327, 0x0, x322, x325); + uint32_t x328; + fiat_p256_uint1 x329; + fiat_p256_addcarryx_u32(&x328, &x329, x327, x320, x323); + uint32_t x330; + fiat_p256_uint1 x331; + fiat_p256_addcarryx_u32(&x330, &x331, x329, 0x0, x321); + uint32_t x332; + fiat_p256_uint1 x333; + fiat_p256_addcarryx_u32(&x332, &x333, 0x0, x324, x298); + uint32_t x334; + fiat_p256_uint1 x335; + fiat_p256_addcarryx_u32(&x334, &x335, x333, x326, x300); + uint32_t x336; + fiat_p256_uint1 x337; + fiat_p256_addcarryx_u32(&x336, &x337, x335, x328, x302); + uint32_t x338; + fiat_p256_uint1 x339; + fiat_p256_addcarryx_u32(&x338, &x339, x337, x330, x304); + uint32_t x340; + fiat_p256_uint1 x341; + fiat_p256_addcarryx_u32(&x340, &x341, x331, 0x0, 0x0); + uint32_t x342; + fiat_p256_uint1 x343; + fiat_p256_addcarryx_u32(&x342, &x343, x339, (fiat_p256_uint1)x340, x306); + uint32_t x344; + fiat_p256_uint1 x345; + fiat_p256_addcarryx_u32(&x344, &x345, x343, 0x0, x308); + uint32_t x346; + fiat_p256_uint1 x347; + fiat_p256_addcarryx_u32(&x346, &x347, x345, x298, x310); + uint32_t x348; + fiat_p256_uint1 x349; + fiat_p256_addcarryx_u32(&x348, &x349, x347, x318, x312); + uint32_t x350; + fiat_p256_uint1 x351; + fiat_p256_addcarryx_u32(&x350, &x351, x349, x319, x316); + uint32_t x352; + fiat_p256_uint1 x353; + fiat_p256_addcarryx_u32(&x352, &x353, 0x0, (arg1[7]), x334); + uint32_t x354; + fiat_p256_uint1 x355; + fiat_p256_addcarryx_u32(&x354, &x355, x353, 0x0, x336); + uint32_t x356; + fiat_p256_uint1 x357; + fiat_p256_addcarryx_u32(&x356, &x357, x355, 0x0, x338); + uint32_t x358; + fiat_p256_uint1 x359; + fiat_p256_addcarryx_u32(&x358, &x359, x357, 0x0, x342); + uint32_t x360; + fiat_p256_uint1 x361; + fiat_p256_addcarryx_u32(&x360, &x361, x359, 0x0, x344); + uint32_t x362; + fiat_p256_uint1 x363; + fiat_p256_addcarryx_u32(&x362, &x363, x361, 0x0, x346); + uint32_t x364; + fiat_p256_uint1 x365; + fiat_p256_addcarryx_u32(&x364, &x365, x363, 0x0, x348); + uint32_t x366; + fiat_p256_uint1 x367; + fiat_p256_addcarryx_u32(&x366, &x367, x365, 0x0, x350); + uint32_t x368; + fiat_p256_uint1 x369; + fiat_p256_addcarryx_u32(&x368, &x369, x351, 0x0, x317); + uint32_t x370; + fiat_p256_uint1 x371; + fiat_p256_addcarryx_u32(&x370, &x371, x367, 0x0, (fiat_p256_uint1)x368); + uint32_t x372; + uint32_t x373; + fiat_p256_mulx_u32(&x372, &x373, x352, UINT32_C(0xffffffff)); + uint32_t x374; + uint32_t x375; + fiat_p256_mulx_u32(&x374, &x375, x352, UINT32_C(0xffffffff)); + uint32_t x376; + uint32_t x377; + fiat_p256_mulx_u32(&x376, &x377, x352, UINT32_C(0xffffffff)); + uint32_t x378; + uint32_t x379; + fiat_p256_mulx_u32(&x378, &x379, x352, UINT32_C(0xffffffff)); + uint32_t x380; + fiat_p256_uint1 x381; + fiat_p256_addcarryx_u32(&x380, &x381, 0x0, x376, x379); + uint32_t x382; + fiat_p256_uint1 x383; + fiat_p256_addcarryx_u32(&x382, &x383, x381, x374, x377); + uint32_t x384; + fiat_p256_uint1 x385; + fiat_p256_addcarryx_u32(&x384, &x385, x383, 0x0, x375); + uint32_t x386; + fiat_p256_uint1 x387; + fiat_p256_addcarryx_u32(&x386, &x387, 0x0, x378, x352); + uint32_t x388; + fiat_p256_uint1 x389; + fiat_p256_addcarryx_u32(&x388, &x389, x387, x380, x354); + uint32_t x390; + fiat_p256_uint1 x391; + fiat_p256_addcarryx_u32(&x390, &x391, x389, x382, x356); + uint32_t x392; + fiat_p256_uint1 x393; + fiat_p256_addcarryx_u32(&x392, &x393, x391, x384, x358); + uint32_t x394; + fiat_p256_uint1 x395; + fiat_p256_addcarryx_u32(&x394, &x395, x385, 0x0, 0x0); + uint32_t x396; + fiat_p256_uint1 x397; + fiat_p256_addcarryx_u32(&x396, &x397, x393, (fiat_p256_uint1)x394, x360); + uint32_t x398; + fiat_p256_uint1 x399; + fiat_p256_addcarryx_u32(&x398, &x399, x397, 0x0, x362); + uint32_t x400; + fiat_p256_uint1 x401; + fiat_p256_addcarryx_u32(&x400, &x401, x399, x352, x364); + uint32_t x402; + fiat_p256_uint1 x403; + fiat_p256_addcarryx_u32(&x402, &x403, x401, x372, x366); + uint32_t x404; + fiat_p256_uint1 x405; + fiat_p256_addcarryx_u32(&x404, &x405, x403, x373, x370); + uint32_t x406; + fiat_p256_uint1 x407; + fiat_p256_subborrowx_u32(&x406, &x407, 0x0, x388, UINT32_C(0xffffffff)); + uint32_t x408; + fiat_p256_uint1 x409; + fiat_p256_subborrowx_u32(&x408, &x409, x407, x390, UINT32_C(0xffffffff)); + uint32_t x410; + fiat_p256_uint1 x411; + fiat_p256_subborrowx_u32(&x410, &x411, x409, x392, UINT32_C(0xffffffff)); + uint32_t x412; + fiat_p256_uint1 x413; + fiat_p256_subborrowx_u32(&x412, &x413, x411, x396, 0x0); + uint32_t x414; + fiat_p256_uint1 x415; + fiat_p256_subborrowx_u32(&x414, &x415, x413, x398, 0x0); + uint32_t x416; + fiat_p256_uint1 x417; + fiat_p256_subborrowx_u32(&x416, &x417, x415, x400, 0x0); + uint32_t x418; + fiat_p256_uint1 x419; + fiat_p256_subborrowx_u32(&x418, &x419, x417, x402, 0x1); + uint32_t x420; + fiat_p256_uint1 x421; + fiat_p256_subborrowx_u32(&x420, &x421, x419, x404, UINT32_C(0xffffffff)); + uint32_t x422; + fiat_p256_uint1 x423; + fiat_p256_addcarryx_u32(&x422, &x423, x405, 0x0, x371); + uint32_t x424; + fiat_p256_uint1 x425; + fiat_p256_subborrowx_u32(&x424, &x425, x421, (fiat_p256_uint1)x422, 0x0); + uint32_t x426; + fiat_p256_cmovznz_u32(&x426, x425, x406, x388); + uint32_t x427; + fiat_p256_cmovznz_u32(&x427, x425, x408, x390); + uint32_t x428; + fiat_p256_cmovznz_u32(&x428, x425, x410, x392); + uint32_t x429; + fiat_p256_cmovznz_u32(&x429, x425, x412, x396); + uint32_t x430; + fiat_p256_cmovznz_u32(&x430, x425, x414, x398); + uint32_t x431; + fiat_p256_cmovznz_u32(&x431, x425, x416, x400); + uint32_t x432; + fiat_p256_cmovznz_u32(&x432, x425, x418, x402); + uint32_t x433; + fiat_p256_cmovznz_u32(&x433, x425, x420, x404); + out1[0] = x426; + out1[1] = x427; + out1[2] = x428; + out1[3] = x429; + out1[4] = x430; + out1[5] = x431; + out1[6] = x432; + out1[7] = x433; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffff] + */ +static void fiat_p256_nonzero(uint32_t* out1, const uint32_t arg1[8]) { + uint32_t x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | ((arg1[4]) | ((arg1[5]) | ((arg1[6]) | ((arg1[7]) | (uint32_t)0x0)))))))); + *out1 = x1; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * arg3: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_selectznz(uint32_t out1[8], fiat_p256_uint1 arg1, const uint32_t arg2[8], const uint32_t arg3[8]) { + uint32_t x1; + fiat_p256_cmovznz_u32(&x1, arg1, (arg2[0]), (arg3[0])); + uint32_t x2; + fiat_p256_cmovznz_u32(&x2, arg1, (arg2[1]), (arg3[1])); + uint32_t x3; + fiat_p256_cmovznz_u32(&x3, arg1, (arg2[2]), (arg3[2])); + uint32_t x4; + fiat_p256_cmovznz_u32(&x4, arg1, (arg2[3]), (arg3[3])); + uint32_t x5; + fiat_p256_cmovznz_u32(&x5, arg1, (arg2[4]), (arg3[4])); + uint32_t x6; + fiat_p256_cmovznz_u32(&x6, arg1, (arg2[5]), (arg3[5])); + uint32_t x7; + fiat_p256_cmovznz_u32(&x7, arg1, (arg2[6]), (arg3[6])); + uint32_t x8; + fiat_p256_cmovznz_u32(&x8, arg1, (arg2[7]), (arg3[7])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; + out1[4] = x5; + out1[5] = x6; + out1[6] = x7; + out1[7] = x8; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + */ +static void fiat_p256_to_bytes(uint8_t out1[32], const uint32_t arg1[8]) { + uint32_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u32(&x1, &x2, 0x0, (arg1[0]), UINT32_C(0xffffffff)); + uint32_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u32(&x3, &x4, x2, (arg1[1]), UINT32_C(0xffffffff)); + uint32_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u32(&x5, &x6, x4, (arg1[2]), UINT32_C(0xffffffff)); + uint32_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u32(&x7, &x8, x6, (arg1[3]), 0x0); + uint32_t x9; + fiat_p256_uint1 x10; + fiat_p256_subborrowx_u32(&x9, &x10, x8, (arg1[4]), 0x0); + uint32_t x11; + fiat_p256_uint1 x12; + fiat_p256_subborrowx_u32(&x11, &x12, x10, (arg1[5]), 0x0); + uint32_t x13; + fiat_p256_uint1 x14; + fiat_p256_subborrowx_u32(&x13, &x14, x12, (arg1[6]), 0x1); + uint32_t x15; + fiat_p256_uint1 x16; + fiat_p256_subborrowx_u32(&x15, &x16, x14, (arg1[7]), UINT32_C(0xffffffff)); + uint32_t x17; + fiat_p256_cmovznz_u32(&x17, x16, 0x0, UINT32_C(0xffffffff)); + uint32_t x18; + fiat_p256_uint1 x19; + fiat_p256_addcarryx_u32(&x18, &x19, 0x0, (x17 & UINT32_C(0xffffffff)), x1); + uint32_t x20; + fiat_p256_uint1 x21; + fiat_p256_addcarryx_u32(&x20, &x21, x19, (x17 & UINT32_C(0xffffffff)), x3); + uint32_t x22; + fiat_p256_uint1 x23; + fiat_p256_addcarryx_u32(&x22, &x23, x21, (x17 & UINT32_C(0xffffffff)), x5); + uint32_t x24; + fiat_p256_uint1 x25; + fiat_p256_addcarryx_u32(&x24, &x25, x23, 0x0, x7); + uint32_t x26; + fiat_p256_uint1 x27; + fiat_p256_addcarryx_u32(&x26, &x27, x25, 0x0, x9); + uint32_t x28; + fiat_p256_uint1 x29; + fiat_p256_addcarryx_u32(&x28, &x29, x27, 0x0, x11); + uint32_t x30; + fiat_p256_uint1 x31; + fiat_p256_addcarryx_u32(&x30, &x31, x29, (fiat_p256_uint1)(x17 & 0x1), x13); + uint32_t x32; + fiat_p256_uint1 x33; + fiat_p256_addcarryx_u32(&x32, &x33, x31, (x17 & UINT32_C(0xffffffff)), x15); + uint32_t x34 = (x18 >> 8); + uint8_t x35 = (uint8_t)(x18 & UINT8_C(0xff)); + uint32_t x36 = (x34 >> 8); + uint8_t x37 = (uint8_t)(x34 & UINT8_C(0xff)); + uint8_t x38 = (uint8_t)(x36 >> 8); + uint8_t x39 = (uint8_t)(x36 & UINT8_C(0xff)); + fiat_p256_uint1 x40 = (fiat_p256_uint1)(x38 >> 8); + uint8_t x41 = (uint8_t)(x38 & UINT8_C(0xff)); + uint32_t x42 = (x40 + x20); + uint32_t x43 = (x42 >> 8); + uint8_t x44 = (uint8_t)(x42 & UINT8_C(0xff)); + uint32_t x45 = (x43 >> 8); + uint8_t x46 = (uint8_t)(x43 & UINT8_C(0xff)); + uint8_t x47 = (uint8_t)(x45 >> 8); + uint8_t x48 = (uint8_t)(x45 & UINT8_C(0xff)); + fiat_p256_uint1 x49 = (fiat_p256_uint1)(x47 >> 8); + uint8_t x50 = (uint8_t)(x47 & UINT8_C(0xff)); + uint32_t x51 = (x49 + x22); + uint32_t x52 = (x51 >> 8); + uint8_t x53 = (uint8_t)(x51 & UINT8_C(0xff)); + uint32_t x54 = (x52 >> 8); + uint8_t x55 = (uint8_t)(x52 & UINT8_C(0xff)); + uint8_t x56 = (uint8_t)(x54 >> 8); + uint8_t x57 = (uint8_t)(x54 & UINT8_C(0xff)); + fiat_p256_uint1 x58 = (fiat_p256_uint1)(x56 >> 8); + uint8_t x59 = (uint8_t)(x56 & UINT8_C(0xff)); + uint32_t x60 = (x58 + x24); + uint32_t x61 = (x60 >> 8); + uint8_t x62 = (uint8_t)(x60 & UINT8_C(0xff)); + uint32_t x63 = (x61 >> 8); + uint8_t x64 = (uint8_t)(x61 & UINT8_C(0xff)); + uint8_t x65 = (uint8_t)(x63 >> 8); + uint8_t x66 = (uint8_t)(x63 & UINT8_C(0xff)); + fiat_p256_uint1 x67 = (fiat_p256_uint1)(x65 >> 8); + uint8_t x68 = (uint8_t)(x65 & UINT8_C(0xff)); + uint32_t x69 = (x67 + x26); + uint32_t x70 = (x69 >> 8); + uint8_t x71 = (uint8_t)(x69 & UINT8_C(0xff)); + uint32_t x72 = (x70 >> 8); + uint8_t x73 = (uint8_t)(x70 & UINT8_C(0xff)); + uint8_t x74 = (uint8_t)(x72 >> 8); + uint8_t x75 = (uint8_t)(x72 & UINT8_C(0xff)); + fiat_p256_uint1 x76 = (fiat_p256_uint1)(x74 >> 8); + uint8_t x77 = (uint8_t)(x74 & UINT8_C(0xff)); + uint32_t x78 = (x76 + x28); + uint32_t x79 = (x78 >> 8); + uint8_t x80 = (uint8_t)(x78 & UINT8_C(0xff)); + uint32_t x81 = (x79 >> 8); + uint8_t x82 = (uint8_t)(x79 & UINT8_C(0xff)); + uint8_t x83 = (uint8_t)(x81 >> 8); + uint8_t x84 = (uint8_t)(x81 & UINT8_C(0xff)); + fiat_p256_uint1 x85 = (fiat_p256_uint1)(x83 >> 8); + uint8_t x86 = (uint8_t)(x83 & UINT8_C(0xff)); + uint32_t x87 = (x85 + x30); + uint32_t x88 = (x87 >> 8); + uint8_t x89 = (uint8_t)(x87 & UINT8_C(0xff)); + uint32_t x90 = (x88 >> 8); + uint8_t x91 = (uint8_t)(x88 & UINT8_C(0xff)); + uint8_t x92 = (uint8_t)(x90 >> 8); + uint8_t x93 = (uint8_t)(x90 & UINT8_C(0xff)); + fiat_p256_uint1 x94 = (fiat_p256_uint1)(x92 >> 8); + uint8_t x95 = (uint8_t)(x92 & UINT8_C(0xff)); + uint32_t x96 = (x94 + x32); + uint32_t x97 = (x96 >> 8); + uint8_t x98 = (uint8_t)(x96 & UINT8_C(0xff)); + uint32_t x99 = (x97 >> 8); + uint8_t x100 = (uint8_t)(x97 & UINT8_C(0xff)); + uint8_t x101 = (uint8_t)(x99 >> 8); + uint8_t x102 = (uint8_t)(x99 & UINT8_C(0xff)); + out1[0] = x35; + out1[1] = x37; + out1[2] = x39; + out1[3] = x41; + out1[4] = x44; + out1[5] = x46; + out1[6] = x48; + out1[7] = x50; + out1[8] = x53; + out1[9] = x55; + out1[10] = x57; + out1[11] = x59; + out1[12] = x62; + out1[13] = x64; + out1[14] = x66; + out1[15] = x68; + out1[16] = x71; + out1[17] = x73; + out1[18] = x75; + out1[19] = x77; + out1[20] = x80; + out1[21] = x82; + out1[22] = x84; + out1[23] = x86; + out1[24] = x89; + out1[25] = x91; + out1[26] = x93; + out1[27] = x95; + out1[28] = x98; + out1[29] = x100; + out1[30] = x102; + out1[31] = x101; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff], [0x0 ~> 0xffffffff]] + */ +static void fiat_p256_from_bytes(uint32_t out1[8], const uint8_t arg1[32]) { + uint32_t x1 = ((uint32_t)(arg1[31]) << 24); + uint32_t x2 = ((uint32_t)(arg1[30]) << 16); + uint32_t x3 = ((uint32_t)(arg1[29]) << 8); + uint8_t x4 = (arg1[28]); + uint32_t x5 = ((uint32_t)(arg1[27]) << 24); + uint32_t x6 = ((uint32_t)(arg1[26]) << 16); + uint32_t x7 = ((uint32_t)(arg1[25]) << 8); + uint8_t x8 = (arg1[24]); + uint32_t x9 = ((uint32_t)(arg1[23]) << 24); + uint32_t x10 = ((uint32_t)(arg1[22]) << 16); + uint32_t x11 = ((uint32_t)(arg1[21]) << 8); + uint8_t x12 = (arg1[20]); + uint32_t x13 = ((uint32_t)(arg1[19]) << 24); + uint32_t x14 = ((uint32_t)(arg1[18]) << 16); + uint32_t x15 = ((uint32_t)(arg1[17]) << 8); + uint8_t x16 = (arg1[16]); + uint32_t x17 = ((uint32_t)(arg1[15]) << 24); + uint32_t x18 = ((uint32_t)(arg1[14]) << 16); + uint32_t x19 = ((uint32_t)(arg1[13]) << 8); + uint8_t x20 = (arg1[12]); + uint32_t x21 = ((uint32_t)(arg1[11]) << 24); + uint32_t x22 = ((uint32_t)(arg1[10]) << 16); + uint32_t x23 = ((uint32_t)(arg1[9]) << 8); + uint8_t x24 = (arg1[8]); + uint32_t x25 = ((uint32_t)(arg1[7]) << 24); + uint32_t x26 = ((uint32_t)(arg1[6]) << 16); + uint32_t x27 = ((uint32_t)(arg1[5]) << 8); + uint8_t x28 = (arg1[4]); + uint32_t x29 = ((uint32_t)(arg1[3]) << 24); + uint32_t x30 = ((uint32_t)(arg1[2]) << 16); + uint32_t x31 = ((uint32_t)(arg1[1]) << 8); + uint8_t x32 = (arg1[0]); + uint32_t x33 = (x32 + (x31 + (x30 + x29))); + fiat_p256_uint1 x34 = (fiat_p256_uint1)((uint64_t)x33 >> 32); + uint32_t x35 = (x33 & UINT32_C(0xffffffff)); + uint32_t x36 = (x4 + (x3 + (x2 + x1))); + uint32_t x37 = (x8 + (x7 + (x6 + x5))); + uint32_t x38 = (x12 + (x11 + (x10 + x9))); + uint32_t x39 = (x16 + (x15 + (x14 + x13))); + uint32_t x40 = (x20 + (x19 + (x18 + x17))); + uint32_t x41 = (x24 + (x23 + (x22 + x21))); + uint32_t x42 = (x28 + (x27 + (x26 + x25))); + uint32_t x43 = (x34 + x42); + fiat_p256_uint1 x44 = (fiat_p256_uint1)((uint64_t)x43 >> 32); + uint32_t x45 = (x43 & UINT32_C(0xffffffff)); + uint32_t x46 = (x44 + x41); + fiat_p256_uint1 x47 = (fiat_p256_uint1)((uint64_t)x46 >> 32); + uint32_t x48 = (x46 & UINT32_C(0xffffffff)); + uint32_t x49 = (x47 + x40); + fiat_p256_uint1 x50 = (fiat_p256_uint1)((uint64_t)x49 >> 32); + uint32_t x51 = (x49 & UINT32_C(0xffffffff)); + uint32_t x52 = (x50 + x39); + fiat_p256_uint1 x53 = (fiat_p256_uint1)((uint64_t)x52 >> 32); + uint32_t x54 = (x52 & UINT32_C(0xffffffff)); + uint32_t x55 = (x53 + x38); + fiat_p256_uint1 x56 = (fiat_p256_uint1)((uint64_t)x55 >> 32); + uint32_t x57 = (x55 & UINT32_C(0xffffffff)); + uint32_t x58 = (x56 + x37); + fiat_p256_uint1 x59 = (fiat_p256_uint1)((uint64_t)x58 >> 32); + uint32_t x60 = (x58 & UINT32_C(0xffffffff)); + uint32_t x61 = (x59 + x36); + out1[0] = x35; + out1[1] = x45; + out1[2] = x48; + out1[3] = x51; + out1[4] = x54; + out1[5] = x57; + out1[6] = x60; + out1[7] = x61; +} + diff --git a/p256_64.c b/p256_64.c new file mode 100644 index 000000000..1449d3175 --- /dev/null +++ b/p256_64.c @@ -0,0 +1,1344 @@ +/* Autogenerated */ +/* curve description: p256 */ +/* requested operations: (all) */ +/* s = 0x10000000000000000000000000000000000000000000000000000000000000000 (from "2^256") */ +/* c = [(26959946667150639794667015087019630673637144422540572481103610249216, 1), (6277101735386680763835789423207666416102355444464034512896, -1), (79228162514264337593543950336, -1), (1, 1)] (from "2^224,1;2^192,-1;2^96,-1;1,1") */ +/* machine_wordsize = 64 (from "64") */ + +#include +typedef unsigned char fiat_p256_uint1; +typedef signed char fiat_p256_int1; +typedef signed __int128 fiat_p256_int128; +typedef unsigned __int128 fiat_p256_uint128; + + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static void fiat_p256_addcarryx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint128 x1 = ((arg1 + (fiat_p256_uint128)arg2) + arg3); + uint64_t x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + fiat_p256_uint1 x3 = (fiat_p256_uint1)(x1 >> 64); + *out1 = x2; + *out2 = x3; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0x1] + */ +static void fiat_p256_subborrowx_u64(uint64_t* out1, fiat_p256_uint1* out2, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_int128 x1 = ((arg2 - (fiat_p256_int128)arg1) - arg3); + fiat_p256_int1 x2 = (fiat_p256_int1)((fiat_p256_uint128)x1 >> 64); + uint64_t x3 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + *out1 = x3; + *out2 = (fiat_p256_uint1)(0x0 - x2); +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0xffffffffffffffff] + * arg2: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + * out2: [0x0 ~> 0xffffffffffffffff] + */ +static void fiat_p256_mulx_u64(uint64_t* out1, uint64_t* out2, uint64_t arg1, uint64_t arg2) { + fiat_p256_uint128 x1 = ((fiat_p256_uint128)arg1 * arg2); + uint64_t x2 = (uint64_t)(x1 & UINT64_C(0xffffffffffffffff)); + uint64_t x3 = (uint64_t)(x1 >> 64); + *out1 = x2; + *out2 = x3; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [0x0 ~> 0xffffffffffffffff] + * arg3: [0x0 ~> 0xffffffffffffffff] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p256_uint1 arg1, uint64_t arg2, uint64_t arg3) { + fiat_p256_uint1 x1 = (!(!arg1)); + uint64_t x2 = ((fiat_p256_int1)(0x0 - x1) & UINT64_C(0xffffffffffffffff)); + uint64_t x3 = ((x2 & arg3) | (uint64_t)((fiat_p256_uint128)(~x2) & arg2)); + *out1 = x3; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_mul(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { + uint64_t x1 = (arg1[1]); + uint64_t x2 = (arg1[2]); + uint64_t x3 = (arg1[3]); + uint64_t x4 = (arg1[0]); + uint64_t x5; + uint64_t x6; + fiat_p256_mulx_u64(&x5, &x6, x4, (arg2[3])); + uint64_t x7; + uint64_t x8; + fiat_p256_mulx_u64(&x7, &x8, x4, (arg2[2])); + uint64_t x9; + uint64_t x10; + fiat_p256_mulx_u64(&x9, &x10, x4, (arg2[1])); + uint64_t x11; + uint64_t x12; + fiat_p256_mulx_u64(&x11, &x12, x4, (arg2[0])); + uint64_t x13; + fiat_p256_uint1 x14; + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x9, x12); + uint64_t x15; + fiat_p256_uint1 x16; + fiat_p256_addcarryx_u64(&x15, &x16, x14, x7, x10); + uint64_t x17; + fiat_p256_uint1 x18; + fiat_p256_addcarryx_u64(&x17, &x18, x16, x5, x8); + uint64_t x19; + fiat_p256_uint1 x20; + fiat_p256_addcarryx_u64(&x19, &x20, x18, 0x0, x6); + uint64_t x21; + uint64_t x22; + fiat_p256_mulx_u64(&x21, &x22, x11, UINT64_C(0xffffffff00000001)); + uint64_t x23; + uint64_t x24; + fiat_p256_mulx_u64(&x23, &x24, x11, UINT32_C(0xffffffff)); + uint64_t x25; + uint64_t x26; + fiat_p256_mulx_u64(&x25, &x26, x11, UINT64_C(0xffffffffffffffff)); + uint64_t x27; + fiat_p256_uint1 x28; + fiat_p256_addcarryx_u64(&x27, &x28, 0x0, x23, x26); + uint64_t x29; + fiat_p256_uint1 x30; + fiat_p256_addcarryx_u64(&x29, &x30, x28, 0x0, x24); + uint64_t x31; + fiat_p256_uint1 x32; + fiat_p256_addcarryx_u64(&x31, &x32, x30, x21, 0x0); + uint64_t x33; + fiat_p256_uint1 x34; + fiat_p256_addcarryx_u64(&x33, &x34, x32, 0x0, x22); + uint64_t x35; + fiat_p256_uint1 x36; + fiat_p256_addcarryx_u64(&x35, &x36, 0x0, x25, x11); + uint64_t x37; + fiat_p256_uint1 x38; + fiat_p256_addcarryx_u64(&x37, &x38, x36, x27, x13); + uint64_t x39; + fiat_p256_uint1 x40; + fiat_p256_addcarryx_u64(&x39, &x40, x38, x29, x15); + uint64_t x41; + fiat_p256_uint1 x42; + fiat_p256_addcarryx_u64(&x41, &x42, x40, x31, x17); + uint64_t x43; + fiat_p256_uint1 x44; + fiat_p256_addcarryx_u64(&x43, &x44, x42, x33, x19); + uint64_t x45; + fiat_p256_uint1 x46; + fiat_p256_addcarryx_u64(&x45, &x46, x44, 0x0, 0x0); + uint64_t x47; + uint64_t x48; + fiat_p256_mulx_u64(&x47, &x48, x1, (arg2[3])); + uint64_t x49; + uint64_t x50; + fiat_p256_mulx_u64(&x49, &x50, x1, (arg2[2])); + uint64_t x51; + uint64_t x52; + fiat_p256_mulx_u64(&x51, &x52, x1, (arg2[1])); + uint64_t x53; + uint64_t x54; + fiat_p256_mulx_u64(&x53, &x54, x1, (arg2[0])); + uint64_t x55; + fiat_p256_uint1 x56; + fiat_p256_addcarryx_u64(&x55, &x56, 0x0, x51, x54); + uint64_t x57; + fiat_p256_uint1 x58; + fiat_p256_addcarryx_u64(&x57, &x58, x56, x49, x52); + uint64_t x59; + fiat_p256_uint1 x60; + fiat_p256_addcarryx_u64(&x59, &x60, x58, x47, x50); + uint64_t x61; + fiat_p256_uint1 x62; + fiat_p256_addcarryx_u64(&x61, &x62, x60, 0x0, x48); + uint64_t x63; + fiat_p256_uint1 x64; + fiat_p256_addcarryx_u64(&x63, &x64, 0x0, x53, x37); + uint64_t x65; + fiat_p256_uint1 x66; + fiat_p256_addcarryx_u64(&x65, &x66, x64, x55, x39); + uint64_t x67; + fiat_p256_uint1 x68; + fiat_p256_addcarryx_u64(&x67, &x68, x66, x57, x41); + uint64_t x69; + fiat_p256_uint1 x70; + fiat_p256_addcarryx_u64(&x69, &x70, x68, x59, x43); + uint64_t x71; + fiat_p256_uint1 x72; + fiat_p256_addcarryx_u64(&x71, &x72, x70, x61, (fiat_p256_uint1)x45); + uint64_t x73; + uint64_t x74; + fiat_p256_mulx_u64(&x73, &x74, x63, UINT64_C(0xffffffff00000001)); + uint64_t x75; + uint64_t x76; + fiat_p256_mulx_u64(&x75, &x76, x63, UINT32_C(0xffffffff)); + uint64_t x77; + uint64_t x78; + fiat_p256_mulx_u64(&x77, &x78, x63, UINT64_C(0xffffffffffffffff)); + uint64_t x79; + fiat_p256_uint1 x80; + fiat_p256_addcarryx_u64(&x79, &x80, 0x0, x75, x78); + uint64_t x81; + fiat_p256_uint1 x82; + fiat_p256_addcarryx_u64(&x81, &x82, x80, 0x0, x76); + uint64_t x83; + fiat_p256_uint1 x84; + fiat_p256_addcarryx_u64(&x83, &x84, x82, x73, 0x0); + uint64_t x85; + fiat_p256_uint1 x86; + fiat_p256_addcarryx_u64(&x85, &x86, x84, 0x0, x74); + uint64_t x87; + fiat_p256_uint1 x88; + fiat_p256_addcarryx_u64(&x87, &x88, 0x0, x77, x63); + uint64_t x89; + fiat_p256_uint1 x90; + fiat_p256_addcarryx_u64(&x89, &x90, x88, x79, x65); + uint64_t x91; + fiat_p256_uint1 x92; + fiat_p256_addcarryx_u64(&x91, &x92, x90, x81, x67); + uint64_t x93; + fiat_p256_uint1 x94; + fiat_p256_addcarryx_u64(&x93, &x94, x92, x83, x69); + uint64_t x95; + fiat_p256_uint1 x96; + fiat_p256_addcarryx_u64(&x95, &x96, x94, x85, x71); + uint64_t x97; + fiat_p256_uint1 x98; + fiat_p256_addcarryx_u64(&x97, &x98, x96, 0x0, x72); + uint64_t x99; + uint64_t x100; + fiat_p256_mulx_u64(&x99, &x100, x2, (arg2[3])); + uint64_t x101; + uint64_t x102; + fiat_p256_mulx_u64(&x101, &x102, x2, (arg2[2])); + uint64_t x103; + uint64_t x104; + fiat_p256_mulx_u64(&x103, &x104, x2, (arg2[1])); + uint64_t x105; + uint64_t x106; + fiat_p256_mulx_u64(&x105, &x106, x2, (arg2[0])); + uint64_t x107; + fiat_p256_uint1 x108; + fiat_p256_addcarryx_u64(&x107, &x108, 0x0, x103, x106); + uint64_t x109; + fiat_p256_uint1 x110; + fiat_p256_addcarryx_u64(&x109, &x110, x108, x101, x104); + uint64_t x111; + fiat_p256_uint1 x112; + fiat_p256_addcarryx_u64(&x111, &x112, x110, x99, x102); + uint64_t x113; + fiat_p256_uint1 x114; + fiat_p256_addcarryx_u64(&x113, &x114, x112, 0x0, x100); + uint64_t x115; + fiat_p256_uint1 x116; + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x105, x89); + uint64_t x117; + fiat_p256_uint1 x118; + fiat_p256_addcarryx_u64(&x117, &x118, x116, x107, x91); + uint64_t x119; + fiat_p256_uint1 x120; + fiat_p256_addcarryx_u64(&x119, &x120, x118, x109, x93); + uint64_t x121; + fiat_p256_uint1 x122; + fiat_p256_addcarryx_u64(&x121, &x122, x120, x111, x95); + uint64_t x123; + fiat_p256_uint1 x124; + fiat_p256_addcarryx_u64(&x123, &x124, x122, x113, x97); + uint64_t x125; + uint64_t x126; + fiat_p256_mulx_u64(&x125, &x126, x115, UINT64_C(0xffffffff00000001)); + uint64_t x127; + uint64_t x128; + fiat_p256_mulx_u64(&x127, &x128, x115, UINT32_C(0xffffffff)); + uint64_t x129; + uint64_t x130; + fiat_p256_mulx_u64(&x129, &x130, x115, UINT64_C(0xffffffffffffffff)); + uint64_t x131; + fiat_p256_uint1 x132; + fiat_p256_addcarryx_u64(&x131, &x132, 0x0, x127, x130); + uint64_t x133; + fiat_p256_uint1 x134; + fiat_p256_addcarryx_u64(&x133, &x134, x132, 0x0, x128); + uint64_t x135; + fiat_p256_uint1 x136; + fiat_p256_addcarryx_u64(&x135, &x136, x134, x125, 0x0); + uint64_t x137; + fiat_p256_uint1 x138; + fiat_p256_addcarryx_u64(&x137, &x138, x136, 0x0, x126); + uint64_t x139; + fiat_p256_uint1 x140; + fiat_p256_addcarryx_u64(&x139, &x140, 0x0, x129, x115); + uint64_t x141; + fiat_p256_uint1 x142; + fiat_p256_addcarryx_u64(&x141, &x142, x140, x131, x117); + uint64_t x143; + fiat_p256_uint1 x144; + fiat_p256_addcarryx_u64(&x143, &x144, x142, x133, x119); + uint64_t x145; + fiat_p256_uint1 x146; + fiat_p256_addcarryx_u64(&x145, &x146, x144, x135, x121); + uint64_t x147; + fiat_p256_uint1 x148; + fiat_p256_addcarryx_u64(&x147, &x148, x146, x137, x123); + uint64_t x149; + fiat_p256_uint1 x150; + fiat_p256_addcarryx_u64(&x149, &x150, x148, 0x0, x124); + uint64_t x151; + uint64_t x152; + fiat_p256_mulx_u64(&x151, &x152, x3, (arg2[3])); + uint64_t x153; + uint64_t x154; + fiat_p256_mulx_u64(&x153, &x154, x3, (arg2[2])); + uint64_t x155; + uint64_t x156; + fiat_p256_mulx_u64(&x155, &x156, x3, (arg2[1])); + uint64_t x157; + uint64_t x158; + fiat_p256_mulx_u64(&x157, &x158, x3, (arg2[0])); + uint64_t x159; + fiat_p256_uint1 x160; + fiat_p256_addcarryx_u64(&x159, &x160, 0x0, x155, x158); + uint64_t x161; + fiat_p256_uint1 x162; + fiat_p256_addcarryx_u64(&x161, &x162, x160, x153, x156); + uint64_t x163; + fiat_p256_uint1 x164; + fiat_p256_addcarryx_u64(&x163, &x164, x162, x151, x154); + uint64_t x165; + fiat_p256_uint1 x166; + fiat_p256_addcarryx_u64(&x165, &x166, x164, 0x0, x152); + uint64_t x167; + fiat_p256_uint1 x168; + fiat_p256_addcarryx_u64(&x167, &x168, 0x0, x157, x141); + uint64_t x169; + fiat_p256_uint1 x170; + fiat_p256_addcarryx_u64(&x169, &x170, x168, x159, x143); + uint64_t x171; + fiat_p256_uint1 x172; + fiat_p256_addcarryx_u64(&x171, &x172, x170, x161, x145); + uint64_t x173; + fiat_p256_uint1 x174; + fiat_p256_addcarryx_u64(&x173, &x174, x172, x163, x147); + uint64_t x175; + fiat_p256_uint1 x176; + fiat_p256_addcarryx_u64(&x175, &x176, x174, x165, x149); + uint64_t x177; + uint64_t x178; + fiat_p256_mulx_u64(&x177, &x178, x167, UINT64_C(0xffffffff00000001)); + uint64_t x179; + uint64_t x180; + fiat_p256_mulx_u64(&x179, &x180, x167, UINT32_C(0xffffffff)); + uint64_t x181; + uint64_t x182; + fiat_p256_mulx_u64(&x181, &x182, x167, UINT64_C(0xffffffffffffffff)); + uint64_t x183; + fiat_p256_uint1 x184; + fiat_p256_addcarryx_u64(&x183, &x184, 0x0, x179, x182); + uint64_t x185; + fiat_p256_uint1 x186; + fiat_p256_addcarryx_u64(&x185, &x186, x184, 0x0, x180); + uint64_t x187; + fiat_p256_uint1 x188; + fiat_p256_addcarryx_u64(&x187, &x188, x186, x177, 0x0); + uint64_t x189; + fiat_p256_uint1 x190; + fiat_p256_addcarryx_u64(&x189, &x190, x188, 0x0, x178); + uint64_t x191; + fiat_p256_uint1 x192; + fiat_p256_addcarryx_u64(&x191, &x192, 0x0, x181, x167); + uint64_t x193; + fiat_p256_uint1 x194; + fiat_p256_addcarryx_u64(&x193, &x194, x192, x183, x169); + uint64_t x195; + fiat_p256_uint1 x196; + fiat_p256_addcarryx_u64(&x195, &x196, x194, x185, x171); + uint64_t x197; + fiat_p256_uint1 x198; + fiat_p256_addcarryx_u64(&x197, &x198, x196, x187, x173); + uint64_t x199; + fiat_p256_uint1 x200; + fiat_p256_addcarryx_u64(&x199, &x200, x198, x189, x175); + uint64_t x201; + fiat_p256_uint1 x202; + fiat_p256_addcarryx_u64(&x201, &x202, x200, 0x0, x176); + uint64_t x203; + fiat_p256_uint1 x204; + fiat_p256_subborrowx_u64(&x203, &x204, 0x0, x193, UINT64_C(0xffffffffffffffff)); + uint64_t x205; + fiat_p256_uint1 x206; + fiat_p256_subborrowx_u64(&x205, &x206, x204, x195, UINT32_C(0xffffffff)); + uint64_t x207; + fiat_p256_uint1 x208; + fiat_p256_subborrowx_u64(&x207, &x208, x206, x197, 0x0); + uint64_t x209; + fiat_p256_uint1 x210; + fiat_p256_subborrowx_u64(&x209, &x210, x208, x199, UINT64_C(0xffffffff00000001)); + uint64_t x211; + fiat_p256_uint1 x212; + fiat_p256_subborrowx_u64(&x211, &x212, x210, x201, 0x0); + uint64_t x213; + fiat_p256_cmovznz_u64(&x213, x212, x203, x193); + uint64_t x214; + fiat_p256_cmovznz_u64(&x214, x212, x205, x195); + uint64_t x215; + fiat_p256_cmovznz_u64(&x215, x212, x207, x197); + uint64_t x216; + fiat_p256_cmovznz_u64(&x216, x212, x209, x199); + out1[0] = x213; + out1[1] = x214; + out1[2] = x215; + out1[3] = x216; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_square(uint64_t out1[4], const uint64_t arg1[4]) { + uint64_t x1 = (arg1[1]); + uint64_t x2 = (arg1[2]); + uint64_t x3 = (arg1[3]); + uint64_t x4 = (arg1[0]); + uint64_t x5; + uint64_t x6; + fiat_p256_mulx_u64(&x5, &x6, x4, (arg1[3])); + uint64_t x7; + uint64_t x8; + fiat_p256_mulx_u64(&x7, &x8, x4, (arg1[2])); + uint64_t x9; + uint64_t x10; + fiat_p256_mulx_u64(&x9, &x10, x4, (arg1[1])); + uint64_t x11; + uint64_t x12; + fiat_p256_mulx_u64(&x11, &x12, x4, (arg1[0])); + uint64_t x13; + fiat_p256_uint1 x14; + fiat_p256_addcarryx_u64(&x13, &x14, 0x0, x9, x12); + uint64_t x15; + fiat_p256_uint1 x16; + fiat_p256_addcarryx_u64(&x15, &x16, x14, x7, x10); + uint64_t x17; + fiat_p256_uint1 x18; + fiat_p256_addcarryx_u64(&x17, &x18, x16, x5, x8); + uint64_t x19; + fiat_p256_uint1 x20; + fiat_p256_addcarryx_u64(&x19, &x20, x18, 0x0, x6); + uint64_t x21; + uint64_t x22; + fiat_p256_mulx_u64(&x21, &x22, x11, UINT64_C(0xffffffff00000001)); + uint64_t x23; + uint64_t x24; + fiat_p256_mulx_u64(&x23, &x24, x11, UINT32_C(0xffffffff)); + uint64_t x25; + uint64_t x26; + fiat_p256_mulx_u64(&x25, &x26, x11, UINT64_C(0xffffffffffffffff)); + uint64_t x27; + fiat_p256_uint1 x28; + fiat_p256_addcarryx_u64(&x27, &x28, 0x0, x23, x26); + uint64_t x29; + fiat_p256_uint1 x30; + fiat_p256_addcarryx_u64(&x29, &x30, x28, 0x0, x24); + uint64_t x31; + fiat_p256_uint1 x32; + fiat_p256_addcarryx_u64(&x31, &x32, x30, x21, 0x0); + uint64_t x33; + fiat_p256_uint1 x34; + fiat_p256_addcarryx_u64(&x33, &x34, x32, 0x0, x22); + uint64_t x35; + fiat_p256_uint1 x36; + fiat_p256_addcarryx_u64(&x35, &x36, 0x0, x25, x11); + uint64_t x37; + fiat_p256_uint1 x38; + fiat_p256_addcarryx_u64(&x37, &x38, x36, x27, x13); + uint64_t x39; + fiat_p256_uint1 x40; + fiat_p256_addcarryx_u64(&x39, &x40, x38, x29, x15); + uint64_t x41; + fiat_p256_uint1 x42; + fiat_p256_addcarryx_u64(&x41, &x42, x40, x31, x17); + uint64_t x43; + fiat_p256_uint1 x44; + fiat_p256_addcarryx_u64(&x43, &x44, x42, x33, x19); + uint64_t x45; + fiat_p256_uint1 x46; + fiat_p256_addcarryx_u64(&x45, &x46, x44, 0x0, 0x0); + uint64_t x47; + uint64_t x48; + fiat_p256_mulx_u64(&x47, &x48, x1, (arg1[3])); + uint64_t x49; + uint64_t x50; + fiat_p256_mulx_u64(&x49, &x50, x1, (arg1[2])); + uint64_t x51; + uint64_t x52; + fiat_p256_mulx_u64(&x51, &x52, x1, (arg1[1])); + uint64_t x53; + uint64_t x54; + fiat_p256_mulx_u64(&x53, &x54, x1, (arg1[0])); + uint64_t x55; + fiat_p256_uint1 x56; + fiat_p256_addcarryx_u64(&x55, &x56, 0x0, x51, x54); + uint64_t x57; + fiat_p256_uint1 x58; + fiat_p256_addcarryx_u64(&x57, &x58, x56, x49, x52); + uint64_t x59; + fiat_p256_uint1 x60; + fiat_p256_addcarryx_u64(&x59, &x60, x58, x47, x50); + uint64_t x61; + fiat_p256_uint1 x62; + fiat_p256_addcarryx_u64(&x61, &x62, x60, 0x0, x48); + uint64_t x63; + fiat_p256_uint1 x64; + fiat_p256_addcarryx_u64(&x63, &x64, 0x0, x53, x37); + uint64_t x65; + fiat_p256_uint1 x66; + fiat_p256_addcarryx_u64(&x65, &x66, x64, x55, x39); + uint64_t x67; + fiat_p256_uint1 x68; + fiat_p256_addcarryx_u64(&x67, &x68, x66, x57, x41); + uint64_t x69; + fiat_p256_uint1 x70; + fiat_p256_addcarryx_u64(&x69, &x70, x68, x59, x43); + uint64_t x71; + fiat_p256_uint1 x72; + fiat_p256_addcarryx_u64(&x71, &x72, x70, x61, (fiat_p256_uint1)x45); + uint64_t x73; + uint64_t x74; + fiat_p256_mulx_u64(&x73, &x74, x63, UINT64_C(0xffffffff00000001)); + uint64_t x75; + uint64_t x76; + fiat_p256_mulx_u64(&x75, &x76, x63, UINT32_C(0xffffffff)); + uint64_t x77; + uint64_t x78; + fiat_p256_mulx_u64(&x77, &x78, x63, UINT64_C(0xffffffffffffffff)); + uint64_t x79; + fiat_p256_uint1 x80; + fiat_p256_addcarryx_u64(&x79, &x80, 0x0, x75, x78); + uint64_t x81; + fiat_p256_uint1 x82; + fiat_p256_addcarryx_u64(&x81, &x82, x80, 0x0, x76); + uint64_t x83; + fiat_p256_uint1 x84; + fiat_p256_addcarryx_u64(&x83, &x84, x82, x73, 0x0); + uint64_t x85; + fiat_p256_uint1 x86; + fiat_p256_addcarryx_u64(&x85, &x86, x84, 0x0, x74); + uint64_t x87; + fiat_p256_uint1 x88; + fiat_p256_addcarryx_u64(&x87, &x88, 0x0, x77, x63); + uint64_t x89; + fiat_p256_uint1 x90; + fiat_p256_addcarryx_u64(&x89, &x90, x88, x79, x65); + uint64_t x91; + fiat_p256_uint1 x92; + fiat_p256_addcarryx_u64(&x91, &x92, x90, x81, x67); + uint64_t x93; + fiat_p256_uint1 x94; + fiat_p256_addcarryx_u64(&x93, &x94, x92, x83, x69); + uint64_t x95; + fiat_p256_uint1 x96; + fiat_p256_addcarryx_u64(&x95, &x96, x94, x85, x71); + uint64_t x97; + fiat_p256_uint1 x98; + fiat_p256_addcarryx_u64(&x97, &x98, x96, 0x0, x72); + uint64_t x99; + uint64_t x100; + fiat_p256_mulx_u64(&x99, &x100, x2, (arg1[3])); + uint64_t x101; + uint64_t x102; + fiat_p256_mulx_u64(&x101, &x102, x2, (arg1[2])); + uint64_t x103; + uint64_t x104; + fiat_p256_mulx_u64(&x103, &x104, x2, (arg1[1])); + uint64_t x105; + uint64_t x106; + fiat_p256_mulx_u64(&x105, &x106, x2, (arg1[0])); + uint64_t x107; + fiat_p256_uint1 x108; + fiat_p256_addcarryx_u64(&x107, &x108, 0x0, x103, x106); + uint64_t x109; + fiat_p256_uint1 x110; + fiat_p256_addcarryx_u64(&x109, &x110, x108, x101, x104); + uint64_t x111; + fiat_p256_uint1 x112; + fiat_p256_addcarryx_u64(&x111, &x112, x110, x99, x102); + uint64_t x113; + fiat_p256_uint1 x114; + fiat_p256_addcarryx_u64(&x113, &x114, x112, 0x0, x100); + uint64_t x115; + fiat_p256_uint1 x116; + fiat_p256_addcarryx_u64(&x115, &x116, 0x0, x105, x89); + uint64_t x117; + fiat_p256_uint1 x118; + fiat_p256_addcarryx_u64(&x117, &x118, x116, x107, x91); + uint64_t x119; + fiat_p256_uint1 x120; + fiat_p256_addcarryx_u64(&x119, &x120, x118, x109, x93); + uint64_t x121; + fiat_p256_uint1 x122; + fiat_p256_addcarryx_u64(&x121, &x122, x120, x111, x95); + uint64_t x123; + fiat_p256_uint1 x124; + fiat_p256_addcarryx_u64(&x123, &x124, x122, x113, x97); + uint64_t x125; + uint64_t x126; + fiat_p256_mulx_u64(&x125, &x126, x115, UINT64_C(0xffffffff00000001)); + uint64_t x127; + uint64_t x128; + fiat_p256_mulx_u64(&x127, &x128, x115, UINT32_C(0xffffffff)); + uint64_t x129; + uint64_t x130; + fiat_p256_mulx_u64(&x129, &x130, x115, UINT64_C(0xffffffffffffffff)); + uint64_t x131; + fiat_p256_uint1 x132; + fiat_p256_addcarryx_u64(&x131, &x132, 0x0, x127, x130); + uint64_t x133; + fiat_p256_uint1 x134; + fiat_p256_addcarryx_u64(&x133, &x134, x132, 0x0, x128); + uint64_t x135; + fiat_p256_uint1 x136; + fiat_p256_addcarryx_u64(&x135, &x136, x134, x125, 0x0); + uint64_t x137; + fiat_p256_uint1 x138; + fiat_p256_addcarryx_u64(&x137, &x138, x136, 0x0, x126); + uint64_t x139; + fiat_p256_uint1 x140; + fiat_p256_addcarryx_u64(&x139, &x140, 0x0, x129, x115); + uint64_t x141; + fiat_p256_uint1 x142; + fiat_p256_addcarryx_u64(&x141, &x142, x140, x131, x117); + uint64_t x143; + fiat_p256_uint1 x144; + fiat_p256_addcarryx_u64(&x143, &x144, x142, x133, x119); + uint64_t x145; + fiat_p256_uint1 x146; + fiat_p256_addcarryx_u64(&x145, &x146, x144, x135, x121); + uint64_t x147; + fiat_p256_uint1 x148; + fiat_p256_addcarryx_u64(&x147, &x148, x146, x137, x123); + uint64_t x149; + fiat_p256_uint1 x150; + fiat_p256_addcarryx_u64(&x149, &x150, x148, 0x0, x124); + uint64_t x151; + uint64_t x152; + fiat_p256_mulx_u64(&x151, &x152, x3, (arg1[3])); + uint64_t x153; + uint64_t x154; + fiat_p256_mulx_u64(&x153, &x154, x3, (arg1[2])); + uint64_t x155; + uint64_t x156; + fiat_p256_mulx_u64(&x155, &x156, x3, (arg1[1])); + uint64_t x157; + uint64_t x158; + fiat_p256_mulx_u64(&x157, &x158, x3, (arg1[0])); + uint64_t x159; + fiat_p256_uint1 x160; + fiat_p256_addcarryx_u64(&x159, &x160, 0x0, x155, x158); + uint64_t x161; + fiat_p256_uint1 x162; + fiat_p256_addcarryx_u64(&x161, &x162, x160, x153, x156); + uint64_t x163; + fiat_p256_uint1 x164; + fiat_p256_addcarryx_u64(&x163, &x164, x162, x151, x154); + uint64_t x165; + fiat_p256_uint1 x166; + fiat_p256_addcarryx_u64(&x165, &x166, x164, 0x0, x152); + uint64_t x167; + fiat_p256_uint1 x168; + fiat_p256_addcarryx_u64(&x167, &x168, 0x0, x157, x141); + uint64_t x169; + fiat_p256_uint1 x170; + fiat_p256_addcarryx_u64(&x169, &x170, x168, x159, x143); + uint64_t x171; + fiat_p256_uint1 x172; + fiat_p256_addcarryx_u64(&x171, &x172, x170, x161, x145); + uint64_t x173; + fiat_p256_uint1 x174; + fiat_p256_addcarryx_u64(&x173, &x174, x172, x163, x147); + uint64_t x175; + fiat_p256_uint1 x176; + fiat_p256_addcarryx_u64(&x175, &x176, x174, x165, x149); + uint64_t x177; + uint64_t x178; + fiat_p256_mulx_u64(&x177, &x178, x167, UINT64_C(0xffffffff00000001)); + uint64_t x179; + uint64_t x180; + fiat_p256_mulx_u64(&x179, &x180, x167, UINT32_C(0xffffffff)); + uint64_t x181; + uint64_t x182; + fiat_p256_mulx_u64(&x181, &x182, x167, UINT64_C(0xffffffffffffffff)); + uint64_t x183; + fiat_p256_uint1 x184; + fiat_p256_addcarryx_u64(&x183, &x184, 0x0, x179, x182); + uint64_t x185; + fiat_p256_uint1 x186; + fiat_p256_addcarryx_u64(&x185, &x186, x184, 0x0, x180); + uint64_t x187; + fiat_p256_uint1 x188; + fiat_p256_addcarryx_u64(&x187, &x188, x186, x177, 0x0); + uint64_t x189; + fiat_p256_uint1 x190; + fiat_p256_addcarryx_u64(&x189, &x190, x188, 0x0, x178); + uint64_t x191; + fiat_p256_uint1 x192; + fiat_p256_addcarryx_u64(&x191, &x192, 0x0, x181, x167); + uint64_t x193; + fiat_p256_uint1 x194; + fiat_p256_addcarryx_u64(&x193, &x194, x192, x183, x169); + uint64_t x195; + fiat_p256_uint1 x196; + fiat_p256_addcarryx_u64(&x195, &x196, x194, x185, x171); + uint64_t x197; + fiat_p256_uint1 x198; + fiat_p256_addcarryx_u64(&x197, &x198, x196, x187, x173); + uint64_t x199; + fiat_p256_uint1 x200; + fiat_p256_addcarryx_u64(&x199, &x200, x198, x189, x175); + uint64_t x201; + fiat_p256_uint1 x202; + fiat_p256_addcarryx_u64(&x201, &x202, x200, 0x0, x176); + uint64_t x203; + fiat_p256_uint1 x204; + fiat_p256_subborrowx_u64(&x203, &x204, 0x0, x193, UINT64_C(0xffffffffffffffff)); + uint64_t x205; + fiat_p256_uint1 x206; + fiat_p256_subborrowx_u64(&x205, &x206, x204, x195, UINT32_C(0xffffffff)); + uint64_t x207; + fiat_p256_uint1 x208; + fiat_p256_subborrowx_u64(&x207, &x208, x206, x197, 0x0); + uint64_t x209; + fiat_p256_uint1 x210; + fiat_p256_subborrowx_u64(&x209, &x210, x208, x199, UINT64_C(0xffffffff00000001)); + uint64_t x211; + fiat_p256_uint1 x212; + fiat_p256_subborrowx_u64(&x211, &x212, x210, x201, 0x0); + uint64_t x213; + fiat_p256_cmovznz_u64(&x213, x212, x203, x193); + uint64_t x214; + fiat_p256_cmovznz_u64(&x214, x212, x205, x195); + uint64_t x215; + fiat_p256_cmovznz_u64(&x215, x212, x207, x197); + uint64_t x216; + fiat_p256_cmovznz_u64(&x216, x212, x209, x199); + out1[0] = x213; + out1[1] = x214; + out1[2] = x215; + out1[3] = x216; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_add(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg2[0]), (arg1[0])); + uint64_t x3; + fiat_p256_uint1 x4; + fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg2[1]), (arg1[1])); + uint64_t x5; + fiat_p256_uint1 x6; + fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg2[2]), (arg1[2])); + uint64_t x7; + fiat_p256_uint1 x8; + fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg2[3]), (arg1[3])); + uint64_t x9; + fiat_p256_uint1 x10; + fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); + uint64_t x11; + fiat_p256_uint1 x12; + fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); + uint64_t x13; + fiat_p256_uint1 x14; + fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); + uint64_t x15; + fiat_p256_uint1 x16; + fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); + uint64_t x17; + fiat_p256_uint1 x18; + fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); + uint64_t x19; + fiat_p256_cmovznz_u64(&x19, x18, x9, x1); + uint64_t x20; + fiat_p256_cmovznz_u64(&x20, x18, x11, x3); + uint64_t x21; + fiat_p256_cmovznz_u64(&x21, x18, x13, x5); + uint64_t x22; + fiat_p256_cmovznz_u64(&x22, x18, x15, x7); + out1[0] = x19; + out1[1] = x20; + out1[2] = x21; + out1[3] = x22; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_sub(uint64_t out1[4], const uint64_t arg1[4], const uint64_t arg2[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); + uint64_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); + uint64_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); + uint64_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); + uint64_t x9; + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + uint64_t x10; + fiat_p256_uint1 x11; + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, (x9 & UINT64_C(0xffffffffffffffff)), x1); + uint64_t x12; + fiat_p256_uint1 x13; + fiat_p256_addcarryx_u64(&x12, &x13, x11, (x9 & UINT32_C(0xffffffff)), x3); + uint64_t x14; + fiat_p256_uint1 x15; + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, x5); + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_addcarryx_u64(&x16, &x17, x15, (x9 & UINT64_C(0xffffffff00000001)), x7); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_opp(uint64_t out1[4], const uint64_t arg1[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, 0x0, (arg1[0])); + uint64_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u64(&x3, &x4, x2, 0x0, (arg1[1])); + uint64_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u64(&x5, &x6, x4, 0x0, (arg1[2])); + uint64_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u64(&x7, &x8, x6, 0x0, (arg1[3])); + uint64_t x9; + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + uint64_t x10; + fiat_p256_uint1 x11; + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, (x9 & UINT64_C(0xffffffffffffffff)), x1); + uint64_t x12; + fiat_p256_uint1 x13; + fiat_p256_addcarryx_u64(&x12, &x13, x11, (x9 & UINT32_C(0xffffffff)), x3); + uint64_t x14; + fiat_p256_uint1 x15; + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, x5); + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_addcarryx_u64(&x16, &x17, x15, (x9 & UINT64_C(0xffffffff00000001)), x7); + out1[0] = x10; + out1[1] = x12; + out1[2] = x14; + out1[3] = x16; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_from_montgomery(uint64_t out1[4], const uint64_t arg1[4]) { + uint64_t x1 = (arg1[0]); + uint64_t x2; + uint64_t x3; + fiat_p256_mulx_u64(&x2, &x3, x1, UINT64_C(0xffffffff00000001)); + uint64_t x4; + uint64_t x5; + fiat_p256_mulx_u64(&x4, &x5, x1, UINT32_C(0xffffffff)); + uint64_t x6; + uint64_t x7; + fiat_p256_mulx_u64(&x6, &x7, x1, UINT64_C(0xffffffffffffffff)); + uint64_t x8; + fiat_p256_uint1 x9; + fiat_p256_addcarryx_u64(&x8, &x9, 0x0, x4, x7); + uint64_t x10; + fiat_p256_uint1 x11; + fiat_p256_addcarryx_u64(&x10, &x11, x9, 0x0, x5); + uint64_t x12; + fiat_p256_uint1 x13; + fiat_p256_addcarryx_u64(&x12, &x13, x11, x2, 0x0); + uint64_t x14; + fiat_p256_uint1 x15; + fiat_p256_addcarryx_u64(&x14, &x15, 0x0, x6, x1); + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_addcarryx_u64(&x16, &x17, x15, x8, 0x0); + uint64_t x18; + fiat_p256_uint1 x19; + fiat_p256_addcarryx_u64(&x18, &x19, x17, x10, 0x0); + uint64_t x20; + fiat_p256_uint1 x21; + fiat_p256_addcarryx_u64(&x20, &x21, x19, x12, 0x0); + uint64_t x22; + fiat_p256_uint1 x23; + fiat_p256_addcarryx_u64(&x22, &x23, x13, 0x0, x3); + uint64_t x24; + fiat_p256_uint1 x25; + fiat_p256_addcarryx_u64(&x24, &x25, x21, x22, 0x0); + uint64_t x26; + fiat_p256_uint1 x27; + fiat_p256_addcarryx_u64(&x26, &x27, 0x0, (arg1[1]), x16); + uint64_t x28; + fiat_p256_uint1 x29; + fiat_p256_addcarryx_u64(&x28, &x29, x27, 0x0, x18); + uint64_t x30; + fiat_p256_uint1 x31; + fiat_p256_addcarryx_u64(&x30, &x31, x29, 0x0, x20); + uint64_t x32; + fiat_p256_uint1 x33; + fiat_p256_addcarryx_u64(&x32, &x33, x31, 0x0, x24); + uint64_t x34; + fiat_p256_uint1 x35; + fiat_p256_addcarryx_u64(&x34, &x35, x25, 0x0, 0x0); + uint64_t x36; + fiat_p256_uint1 x37; + fiat_p256_addcarryx_u64(&x36, &x37, x33, 0x0, (fiat_p256_uint1)x34); + uint64_t x38; + uint64_t x39; + fiat_p256_mulx_u64(&x38, &x39, x26, UINT64_C(0xffffffff00000001)); + uint64_t x40; + uint64_t x41; + fiat_p256_mulx_u64(&x40, &x41, x26, UINT32_C(0xffffffff)); + uint64_t x42; + uint64_t x43; + fiat_p256_mulx_u64(&x42, &x43, x26, UINT64_C(0xffffffffffffffff)); + uint64_t x44; + fiat_p256_uint1 x45; + fiat_p256_addcarryx_u64(&x44, &x45, 0x0, x40, x43); + uint64_t x46; + fiat_p256_uint1 x47; + fiat_p256_addcarryx_u64(&x46, &x47, x45, 0x0, x41); + uint64_t x48; + fiat_p256_uint1 x49; + fiat_p256_addcarryx_u64(&x48, &x49, x47, x38, 0x0); + uint64_t x50; + fiat_p256_uint1 x51; + fiat_p256_addcarryx_u64(&x50, &x51, 0x0, x42, x26); + uint64_t x52; + fiat_p256_uint1 x53; + fiat_p256_addcarryx_u64(&x52, &x53, x51, x44, x28); + uint64_t x54; + fiat_p256_uint1 x55; + fiat_p256_addcarryx_u64(&x54, &x55, x53, x46, x30); + uint64_t x56; + fiat_p256_uint1 x57; + fiat_p256_addcarryx_u64(&x56, &x57, x55, x48, x32); + uint64_t x58; + fiat_p256_uint1 x59; + fiat_p256_addcarryx_u64(&x58, &x59, x49, 0x0, x39); + uint64_t x60; + fiat_p256_uint1 x61; + fiat_p256_addcarryx_u64(&x60, &x61, x57, x58, (fiat_p256_uint1)x36); + uint64_t x62; + fiat_p256_uint1 x63; + fiat_p256_addcarryx_u64(&x62, &x63, 0x0, (arg1[2]), x52); + uint64_t x64; + fiat_p256_uint1 x65; + fiat_p256_addcarryx_u64(&x64, &x65, x63, 0x0, x54); + uint64_t x66; + fiat_p256_uint1 x67; + fiat_p256_addcarryx_u64(&x66, &x67, x65, 0x0, x56); + uint64_t x68; + fiat_p256_uint1 x69; + fiat_p256_addcarryx_u64(&x68, &x69, x67, 0x0, x60); + uint64_t x70; + fiat_p256_uint1 x71; + fiat_p256_addcarryx_u64(&x70, &x71, x61, 0x0, x37); + uint64_t x72; + fiat_p256_uint1 x73; + fiat_p256_addcarryx_u64(&x72, &x73, x69, 0x0, (fiat_p256_uint1)x70); + uint64_t x74; + uint64_t x75; + fiat_p256_mulx_u64(&x74, &x75, x62, UINT64_C(0xffffffff00000001)); + uint64_t x76; + uint64_t x77; + fiat_p256_mulx_u64(&x76, &x77, x62, UINT32_C(0xffffffff)); + uint64_t x78; + uint64_t x79; + fiat_p256_mulx_u64(&x78, &x79, x62, UINT64_C(0xffffffffffffffff)); + uint64_t x80; + fiat_p256_uint1 x81; + fiat_p256_addcarryx_u64(&x80, &x81, 0x0, x76, x79); + uint64_t x82; + fiat_p256_uint1 x83; + fiat_p256_addcarryx_u64(&x82, &x83, x81, 0x0, x77); + uint64_t x84; + fiat_p256_uint1 x85; + fiat_p256_addcarryx_u64(&x84, &x85, x83, x74, 0x0); + uint64_t x86; + fiat_p256_uint1 x87; + fiat_p256_addcarryx_u64(&x86, &x87, 0x0, x78, x62); + uint64_t x88; + fiat_p256_uint1 x89; + fiat_p256_addcarryx_u64(&x88, &x89, x87, x80, x64); + uint64_t x90; + fiat_p256_uint1 x91; + fiat_p256_addcarryx_u64(&x90, &x91, x89, x82, x66); + uint64_t x92; + fiat_p256_uint1 x93; + fiat_p256_addcarryx_u64(&x92, &x93, x91, x84, x68); + uint64_t x94; + fiat_p256_uint1 x95; + fiat_p256_addcarryx_u64(&x94, &x95, x85, 0x0, x75); + uint64_t x96; + fiat_p256_uint1 x97; + fiat_p256_addcarryx_u64(&x96, &x97, x93, x94, (fiat_p256_uint1)x72); + uint64_t x98; + fiat_p256_uint1 x99; + fiat_p256_addcarryx_u64(&x98, &x99, 0x0, (arg1[3]), x88); + uint64_t x100; + fiat_p256_uint1 x101; + fiat_p256_addcarryx_u64(&x100, &x101, x99, 0x0, x90); + uint64_t x102; + fiat_p256_uint1 x103; + fiat_p256_addcarryx_u64(&x102, &x103, x101, 0x0, x92); + uint64_t x104; + fiat_p256_uint1 x105; + fiat_p256_addcarryx_u64(&x104, &x105, x103, 0x0, x96); + uint64_t x106; + fiat_p256_uint1 x107; + fiat_p256_addcarryx_u64(&x106, &x107, x97, 0x0, x73); + uint64_t x108; + fiat_p256_uint1 x109; + fiat_p256_addcarryx_u64(&x108, &x109, x105, 0x0, (fiat_p256_uint1)x106); + uint64_t x110; + uint64_t x111; + fiat_p256_mulx_u64(&x110, &x111, x98, UINT64_C(0xffffffff00000001)); + uint64_t x112; + uint64_t x113; + fiat_p256_mulx_u64(&x112, &x113, x98, UINT32_C(0xffffffff)); + uint64_t x114; + uint64_t x115; + fiat_p256_mulx_u64(&x114, &x115, x98, UINT64_C(0xffffffffffffffff)); + uint64_t x116; + fiat_p256_uint1 x117; + fiat_p256_addcarryx_u64(&x116, &x117, 0x0, x112, x115); + uint64_t x118; + fiat_p256_uint1 x119; + fiat_p256_addcarryx_u64(&x118, &x119, x117, 0x0, x113); + uint64_t x120; + fiat_p256_uint1 x121; + fiat_p256_addcarryx_u64(&x120, &x121, x119, x110, 0x0); + uint64_t x122; + fiat_p256_uint1 x123; + fiat_p256_addcarryx_u64(&x122, &x123, 0x0, x114, x98); + uint64_t x124; + fiat_p256_uint1 x125; + fiat_p256_addcarryx_u64(&x124, &x125, x123, x116, x100); + uint64_t x126; + fiat_p256_uint1 x127; + fiat_p256_addcarryx_u64(&x126, &x127, x125, x118, x102); + uint64_t x128; + fiat_p256_uint1 x129; + fiat_p256_addcarryx_u64(&x128, &x129, x127, x120, x104); + uint64_t x130; + fiat_p256_uint1 x131; + fiat_p256_addcarryx_u64(&x130, &x131, x121, 0x0, x111); + uint64_t x132; + fiat_p256_uint1 x133; + fiat_p256_addcarryx_u64(&x132, &x133, x129, x130, (fiat_p256_uint1)x108); + uint64_t x134; + fiat_p256_uint1 x135; + fiat_p256_subborrowx_u64(&x134, &x135, 0x0, x124, UINT64_C(0xffffffffffffffff)); + uint64_t x136; + fiat_p256_uint1 x137; + fiat_p256_subborrowx_u64(&x136, &x137, x135, x126, UINT32_C(0xffffffff)); + uint64_t x138; + fiat_p256_uint1 x139; + fiat_p256_subborrowx_u64(&x138, &x139, x137, x128, 0x0); + uint64_t x140; + fiat_p256_uint1 x141; + fiat_p256_subborrowx_u64(&x140, &x141, x139, x132, UINT64_C(0xffffffff00000001)); + uint64_t x142; + fiat_p256_uint1 x143; + fiat_p256_addcarryx_u64(&x142, &x143, x133, 0x0, x109); + uint64_t x144; + fiat_p256_uint1 x145; + fiat_p256_subborrowx_u64(&x144, &x145, x141, (fiat_p256_uint1)x142, 0x0); + uint64_t x146; + fiat_p256_cmovznz_u64(&x146, x145, x134, x124); + uint64_t x147; + fiat_p256_cmovznz_u64(&x147, x145, x136, x126); + uint64_t x148; + fiat_p256_cmovznz_u64(&x148, x145, x138, x128); + uint64_t x149; + fiat_p256_cmovznz_u64(&x149, x145, x140, x132); + out1[0] = x146; + out1[1] = x147; + out1[2] = x148; + out1[3] = x149; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [0x0 ~> 0xffffffffffffffff] + */ +static void fiat_p256_nonzero(uint64_t* out1, const uint64_t arg1[4]) { + uint64_t x1 = ((arg1[0]) | ((arg1[1]) | ((arg1[2]) | ((arg1[3]) | (uint64_t)0x0)))); + *out1 = x1; +} + +/* + * Input Bounds: + * arg1: [0x0 ~> 0x1] + * arg2: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * arg3: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_selectznz(uint64_t out1[4], fiat_p256_uint1 arg1, const uint64_t arg2[4], const uint64_t arg3[4]) { + uint64_t x1; + fiat_p256_cmovznz_u64(&x1, arg1, (arg2[0]), (arg3[0])); + uint64_t x2; + fiat_p256_cmovznz_u64(&x2, arg1, (arg2[1]), (arg3[1])); + uint64_t x3; + fiat_p256_cmovznz_u64(&x3, arg1, (arg2[2]), (arg3[2])); + uint64_t x4; + fiat_p256_cmovznz_u64(&x4, arg1, (arg2[3]), (arg3[3])); + out1[0] = x1; + out1[1] = x2; + out1[2] = x3; + out1[3] = x4; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + * Output Bounds: + * out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + */ +static void fiat_p256_to_bytes(uint8_t out1[32], const uint64_t arg1[4]) { + uint64_t x1; + fiat_p256_uint1 x2; + fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), UINT64_C(0xffffffffffffffff)); + uint64_t x3; + fiat_p256_uint1 x4; + fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), UINT32_C(0xffffffff)); + uint64_t x5; + fiat_p256_uint1 x6; + fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), 0x0); + uint64_t x7; + fiat_p256_uint1 x8; + fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), UINT64_C(0xffffffff00000001)); + uint64_t x9; + fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); + uint64_t x10; + fiat_p256_uint1 x11; + fiat_p256_addcarryx_u64(&x10, &x11, 0x0, (x9 & UINT64_C(0xffffffffffffffff)), x1); + uint64_t x12; + fiat_p256_uint1 x13; + fiat_p256_addcarryx_u64(&x12, &x13, x11, (x9 & UINT32_C(0xffffffff)), x3); + uint64_t x14; + fiat_p256_uint1 x15; + fiat_p256_addcarryx_u64(&x14, &x15, x13, 0x0, x5); + uint64_t x16; + fiat_p256_uint1 x17; + fiat_p256_addcarryx_u64(&x16, &x17, x15, (x9 & UINT64_C(0xffffffff00000001)), x7); + uint64_t x18 = (x10 >> 8); + uint8_t x19 = (uint8_t)(x10 & UINT8_C(0xff)); + uint64_t x20 = (x18 >> 8); + uint8_t x21 = (uint8_t)(x18 & UINT8_C(0xff)); + uint64_t x22 = (x20 >> 8); + uint8_t x23 = (uint8_t)(x20 & UINT8_C(0xff)); + uint64_t x24 = (x22 >> 8); + uint8_t x25 = (uint8_t)(x22 & UINT8_C(0xff)); + uint64_t x26 = (x24 >> 8); + uint8_t x27 = (uint8_t)(x24 & UINT8_C(0xff)); + uint64_t x28 = (x26 >> 8); + uint8_t x29 = (uint8_t)(x26 & UINT8_C(0xff)); + uint8_t x30 = (uint8_t)(x28 >> 8); + uint8_t x31 = (uint8_t)(x28 & UINT8_C(0xff)); + fiat_p256_uint1 x32 = (fiat_p256_uint1)(x30 >> 8); + uint8_t x33 = (uint8_t)(x30 & UINT8_C(0xff)); + uint64_t x34 = (x32 + x12); + uint64_t x35 = (x34 >> 8); + uint8_t x36 = (uint8_t)(x34 & UINT8_C(0xff)); + uint64_t x37 = (x35 >> 8); + uint8_t x38 = (uint8_t)(x35 & UINT8_C(0xff)); + uint64_t x39 = (x37 >> 8); + uint8_t x40 = (uint8_t)(x37 & UINT8_C(0xff)); + uint64_t x41 = (x39 >> 8); + uint8_t x42 = (uint8_t)(x39 & UINT8_C(0xff)); + uint64_t x43 = (x41 >> 8); + uint8_t x44 = (uint8_t)(x41 & UINT8_C(0xff)); + uint64_t x45 = (x43 >> 8); + uint8_t x46 = (uint8_t)(x43 & UINT8_C(0xff)); + uint8_t x47 = (uint8_t)(x45 >> 8); + uint8_t x48 = (uint8_t)(x45 & UINT8_C(0xff)); + fiat_p256_uint1 x49 = (fiat_p256_uint1)(x47 >> 8); + uint8_t x50 = (uint8_t)(x47 & UINT8_C(0xff)); + uint64_t x51 = (x49 + x14); + uint64_t x52 = (x51 >> 8); + uint8_t x53 = (uint8_t)(x51 & UINT8_C(0xff)); + uint64_t x54 = (x52 >> 8); + uint8_t x55 = (uint8_t)(x52 & UINT8_C(0xff)); + uint64_t x56 = (x54 >> 8); + uint8_t x57 = (uint8_t)(x54 & UINT8_C(0xff)); + uint64_t x58 = (x56 >> 8); + uint8_t x59 = (uint8_t)(x56 & UINT8_C(0xff)); + uint64_t x60 = (x58 >> 8); + uint8_t x61 = (uint8_t)(x58 & UINT8_C(0xff)); + uint64_t x62 = (x60 >> 8); + uint8_t x63 = (uint8_t)(x60 & UINT8_C(0xff)); + uint8_t x64 = (uint8_t)(x62 >> 8); + uint8_t x65 = (uint8_t)(x62 & UINT8_C(0xff)); + fiat_p256_uint1 x66 = (fiat_p256_uint1)(x64 >> 8); + uint8_t x67 = (uint8_t)(x64 & UINT8_C(0xff)); + uint64_t x68 = (x66 + x16); + uint64_t x69 = (x68 >> 8); + uint8_t x70 = (uint8_t)(x68 & UINT8_C(0xff)); + uint64_t x71 = (x69 >> 8); + uint8_t x72 = (uint8_t)(x69 & UINT8_C(0xff)); + uint64_t x73 = (x71 >> 8); + uint8_t x74 = (uint8_t)(x71 & UINT8_C(0xff)); + uint64_t x75 = (x73 >> 8); + uint8_t x76 = (uint8_t)(x73 & UINT8_C(0xff)); + uint64_t x77 = (x75 >> 8); + uint8_t x78 = (uint8_t)(x75 & UINT8_C(0xff)); + uint64_t x79 = (x77 >> 8); + uint8_t x80 = (uint8_t)(x77 & UINT8_C(0xff)); + uint8_t x81 = (uint8_t)(x79 >> 8); + uint8_t x82 = (uint8_t)(x79 & UINT8_C(0xff)); + out1[0] = x19; + out1[1] = x21; + out1[2] = x23; + out1[3] = x25; + out1[4] = x27; + out1[5] = x29; + out1[6] = x31; + out1[7] = x33; + out1[8] = x36; + out1[9] = x38; + out1[10] = x40; + out1[11] = x42; + out1[12] = x44; + out1[13] = x46; + out1[14] = x48; + out1[15] = x50; + out1[16] = x53; + out1[17] = x55; + out1[18] = x57; + out1[19] = x59; + out1[20] = x61; + out1[21] = x63; + out1[22] = x65; + out1[23] = x67; + out1[24] = x70; + out1[25] = x72; + out1[26] = x74; + out1[27] = x76; + out1[28] = x78; + out1[29] = x80; + out1[30] = x82; + out1[31] = x81; +} + +/* + * Input Bounds: + * arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff]] + * Output Bounds: + * out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] + */ +static void fiat_p256_from_bytes(uint64_t out1[4], const uint8_t arg1[32]) { + uint64_t x1 = ((uint64_t)(arg1[31]) << 56); + uint64_t x2 = ((uint64_t)(arg1[30]) << 48); + uint64_t x3 = ((uint64_t)(arg1[29]) << 40); + uint64_t x4 = ((uint64_t)(arg1[28]) << 32); + uint64_t x5 = ((uint64_t)(arg1[27]) << 24); + uint64_t x6 = ((uint64_t)(arg1[26]) << 16); + uint64_t x7 = ((uint64_t)(arg1[25]) << 8); + uint8_t x8 = (arg1[24]); + uint64_t x9 = ((uint64_t)(arg1[23]) << 56); + uint64_t x10 = ((uint64_t)(arg1[22]) << 48); + uint64_t x11 = ((uint64_t)(arg1[21]) << 40); + uint64_t x12 = ((uint64_t)(arg1[20]) << 32); + uint64_t x13 = ((uint64_t)(arg1[19]) << 24); + uint64_t x14 = ((uint64_t)(arg1[18]) << 16); + uint64_t x15 = ((uint64_t)(arg1[17]) << 8); + uint8_t x16 = (arg1[16]); + uint64_t x17 = ((uint64_t)(arg1[15]) << 56); + uint64_t x18 = ((uint64_t)(arg1[14]) << 48); + uint64_t x19 = ((uint64_t)(arg1[13]) << 40); + uint64_t x20 = ((uint64_t)(arg1[12]) << 32); + uint64_t x21 = ((uint64_t)(arg1[11]) << 24); + uint64_t x22 = ((uint64_t)(arg1[10]) << 16); + uint64_t x23 = ((uint64_t)(arg1[9]) << 8); + uint8_t x24 = (arg1[8]); + uint64_t x25 = ((uint64_t)(arg1[7]) << 56); + uint64_t x26 = ((uint64_t)(arg1[6]) << 48); + uint64_t x27 = ((uint64_t)(arg1[5]) << 40); + uint64_t x28 = ((uint64_t)(arg1[4]) << 32); + uint64_t x29 = ((uint64_t)(arg1[3]) << 24); + uint64_t x30 = ((uint64_t)(arg1[2]) << 16); + uint64_t x31 = ((uint64_t)(arg1[1]) << 8); + uint8_t x32 = (arg1[0]); + uint64_t x33 = (x32 + (x31 + (x30 + (x29 + (x28 + (x27 + (x26 + x25))))))); + fiat_p256_uint1 x34 = (fiat_p256_uint1)((fiat_p256_uint128)x33 >> 64); + uint64_t x35 = (x33 & UINT64_C(0xffffffffffffffff)); + uint64_t x36 = (x8 + (x7 + (x6 + (x5 + (x4 + (x3 + (x2 + x1))))))); + uint64_t x37 = (x16 + (x15 + (x14 + (x13 + (x12 + (x11 + (x10 + x9))))))); + uint64_t x38 = (x24 + (x23 + (x22 + (x21 + (x20 + (x19 + (x18 + x17))))))); + uint64_t x39 = (x34 + x38); + fiat_p256_uint1 x40 = (fiat_p256_uint1)((fiat_p256_uint128)x39 >> 64); + uint64_t x41 = (x39 & UINT64_C(0xffffffffffffffff)); + uint64_t x42 = (x40 + x37); + fiat_p256_uint1 x43 = (fiat_p256_uint1)((fiat_p256_uint128)x42 >> 64); + uint64_t x44 = (x42 & UINT64_C(0xffffffffffffffff)); + uint64_t x45 = (x43 + x36); + out1[0] = x35; + out1[1] = x41; + out1[2] = x44; + out1[3] = x45; +} + diff --git a/src/Experiments/NewPipeline/Arithmetic.v b/src/Experiments/NewPipeline/Arithmetic.v index 398fd17bc..4bf3c55e6 100644 --- a/src/Experiments/NewPipeline/Arithmetic.v +++ b/src/Experiments/NewPipeline/Arithmetic.v @@ -10,8 +10,8 @@ Require Import Crypto.Util.ListUtil Coq.Lists.List Crypto.Util.NatUtil. Require Import QArith.QArith_base QArith.Qround Crypto.Util.QUtil. Require Import Crypto.Algebra.Ring Crypto.Util.Decidable.Bool2Prop. Require Import Crypto.Arithmetic.BarrettReduction.Generalized. -Require Import Crypto.Arithmetic.MontgomeryReduction.Definition. -Require Import Crypto.Arithmetic.MontgomeryReduction.Proofs. +Require Import Crypto.Arithmetic.ModularArithmeticTheorems. +Require Import Crypto.Arithmetic.PrimeFieldTheorems. Require Import Crypto.Util.ZUtil.Tactics.PullPush.Modulo. Require Import Crypto.Util.Tactics.RunTacticAsConstr. Require Import Crypto.Util.Tactics.Head. @@ -20,6 +20,7 @@ Require Import Crypto.Util.OptionList. Require Import Crypto.Util.Prod. Require Import Crypto.Util.Sum. Require Import Crypto.Util.Bool. +Require Import Crypto.Util.Sigma. Require Import Crypto.Util.ZUtil. Require Import Crypto.Util.ZUtil.Modulo Crypto.Util.ZUtil.Div Crypto.Util.ZUtil.Hints.Core. Require Import Crypto.Util.ZUtil.Hints.PullPush. @@ -43,6 +44,7 @@ Require Import Crypto.Util.ZUtil.EquivModulo. Require Import Crypto.Util.Prod. Require Import Crypto.Util.CPSNotations. Require Import Crypto.Util.Equality. +Require Import Crypto.Util.Tactics.SetEvars. Import ListNotations. Local Open Scope Z_scope. Module Associational. @@ -499,6 +501,10 @@ Module Positional. Section Positional. autorewrite with push_eval cancel_pair; ring. Qed. + Lemma eval_snoc_S n x y : n = length x -> eval (S n) (x ++ [y]) = eval n x + weight n * y. + Proof. intros; erewrite eval_snoc; eauto. Qed. + Hint Rewrite eval_snoc_S : push_eval. + (* SKIP over this: zeros, add_to_nth *) Local Ltac push := autorewrite with push_eval push_map distr_length push_flat_map push_fold_right push_nth_default cancel_pair natsimplify. @@ -534,6 +540,9 @@ Module Positional. Section Positional. end; lia. Qed. Hint Rewrite @eval_add_to_nth eval_zeros eval_combine_zeros : push_eval. + Lemma zeros_ext_map {A} n (p : list A) : length p = n -> zeros n = map (fun _ => 0) p. + Proof. cbv [zeros]; intro; subst; induction p; cbn; congruence. Qed. + Definition place (t:Z*Z) (i:nat) : nat * Z := nat_rect (fun _ => unit -> (nat * Z)%type) @@ -584,11 +593,52 @@ Module Positional. Section Positional. push; omega. Qed. Hint Rewrite eval_extend_to_length : push_eval. - Lemma length_eval_extend_to_length n_in n_out p : + Lemma length_extend_to_length n_in n_out p : length p = n_in -> (n_in <= n_out)%nat -> length (extend_to_length n_in n_out p) = n_out. Proof. cbv [extend_to_length]; intros; distr_length. Qed. - Hint Rewrite length_eval_extend_to_length : distr_length. + Hint Rewrite length_extend_to_length : distr_length. + + Definition drop_high_to_length (n : nat) (p:list Z) : list Z := + firstn n p. + (* + Lemma eval_drop_high_to_length n m p : + (forall i, weight (S i) mod weight i = 0) -> length p = m -> (n <= m)%nat -> + eval n (drop_high_to_length n p) mod weight n + = eval m p mod weight n. + Proof. + cbv [eval drop_high_to_length to_associational]; intros. + replace m with (n + (m - n))%nat in * by (f_equal; omega). + generalize dependent (m - n)%nat; clear m; intro m; intros H' H''. + rewrite seq_add, map_app, <- (firstn_skipn n p), combine_app_samelength, firstn_skipn, Associational.eval_app; + push; try omega **. + rewrite <- (Z.add_0_r (Associational.eval _)) at 1. + apply Z.add_mod_Proper; [ reflexivity | cbv [Z.equiv_modulo] ]. + generalize (skipn_length n p); rewrite H', minus_plus. + generalize (skipn n p); clear dependent p; clear H''; intros p Hp. + rewrite Zmod_0_l. + subst. + cbv [Associational.eval]. + revert n; induction p as [|p ps IHps]; intro; [ reflexivity | ]. + cbn in *. + push_Zmod; pull_Zmod; autorewrite with zsimplify_const. + rewrite <- IHps. + { cbn; reflexivity + Search (0 mod _). + rewrite Z.mod_0_l + Search (?x + ?y - ?x)%nat. + Search Z.equiv_modulo Proper. + pose proof H as H''. + rewrite <- (firstn_skipn n p) in H''. + distr_length. + + rewrite Nat.min_l in H'' by omega. + Qed. + Hint Rewrite eval_drop_high_to_length : push_eval.*) + Lemma length_drop_high_to_length n p : + length (drop_high_to_length n p) = Nat.min n (length p). + Proof. cbv [drop_high_to_length]; intros; distr_length. Qed. + Hint Rewrite length_drop_high_to_length : distr_length. Section mulmod. Context (s:Z) (s_nz:s <> 0) @@ -646,6 +696,7 @@ Module Positional. Section Positional. Lemma length_carry n m index p : length (carry n m index p) = m. Proof. cbv [carry]; distr_length. Qed. + Hint Rewrite length_carry : distr_length. Lemma eval_carry n m i p: (n <> 0%nat) -> (m <> 0%nat) -> weight (S i) / weight i <> 0 -> eval m (carry n m i p) = eval n p. @@ -712,6 +763,12 @@ Module Positional. Section Positional. apply fold_right_invariant; [|intro; rewrite <-in_rev]; intros; push; auto. Qed. Hint Rewrite @eval_chained_carries_no_reduce : push_eval. + Lemma length_chained_carries_no_reduce n p idxs + : length p = n -> length (@chained_carries_no_reduce n p idxs) = n. + Proof. + intros; cbv [chained_carries_no_reduce]; induction (rev idxs) as [|x xs IHxs]; + cbn [fold_right]; distr_length. + Qed. Hint Rewrite @length_chained_carries_no_reduce : distr_length. (* Reverse of [eval]; translate from Z to basesystem by putting everything in first digit and then carrying. *) @@ -727,9 +784,22 @@ Module Positional. Section Positional. : length (encode n s c x) = n. Proof. cbv [encode]; repeat distr_length. Qed. + (* Reverse of [eval]; translate from Z to basesystem by putting + everything in first digit and then carrying, but without reduction. *) + Definition encode_no_reduce n (x : Z) : list Z := + chained_carries_no_reduce n (from_associational n [(1,x)]) (seq 0 n). + Lemma eval_encode_no_reduce n x : + (n <> 0%nat) -> + (forall i, In i (seq 0 n) -> weight (S i) / weight i <> 0) -> + eval n (encode_no_reduce n x) = x. + Proof using Type*. cbv [encode_no_reduce]; intros; push; auto; f_equal; omega. Qed. + Lemma length_encode_no_reduce n x + : length (encode_no_reduce n x) = n. + Proof. cbv [encode_no_reduce]; repeat distr_length. Qed. + End Carries. - Hint Rewrite @eval_encode : push_eval. - Hint Rewrite @length_encode : distr_length. + Hint Rewrite @eval_encode @eval_encode_no_reduce @eval_carry @eval_carry_reduce @eval_chained_carries @eval_chained_carries_no_reduce : push_eval. + Hint Rewrite @length_encode @length_encode_no_reduce @length_carry @length_carry_reduce @length_chained_carries @length_chained_carries_no_reduce : distr_length. Section sub. Context (n:nat) @@ -840,8 +910,8 @@ Module Positional. Section Positional. End select. End Positional. (* Hint Rewrite disappears after the end of a section *) -Hint Rewrite length_zeros length_add_to_nth length_from_associational @length_add @length_carry_reduce @length_chained_carries @length_encode @length_sub @length_opp @length_select @length_zselect @length_select_min : distr_length. -Hint Rewrite @eval_select @eval_zselect : push_eval. +Hint Rewrite length_zeros length_add_to_nth length_from_associational @length_add @length_carry_reduce @length_chained_carries @length_encode @length_sub @length_opp @length_select @length_zselect @length_select_min @length_extend_to_length @length_drop_high_to_length : distr_length. +Hint Rewrite @eval_zeros @eval_nil @eval_snoc_S @eval_select @eval_zselect @eval_extend_to_length (*@eval_drop_high_to_length*) : push_eval. Section Positional_nonuniform. Context (weight weight' : nat -> Z). @@ -2099,7 +2169,15 @@ Module Rows. (* Subtract q if and only if p >= q. *) Definition conditional_sub n (p q:list Z) := let '(v, c) := sub n p q in - Positional.select c v p. + Positional.select (-c) v p. + + (* the carry will be 0 unless we underflow--we do the addition only + in the underflow case *) + Definition sub_then_maybe_add n mask (p q r:list Z) := + let '(p_minus_q, c) := sub n p q in + let rr := Positional.zselect mask (-c) r in + let '(res, c') := add n p_minus_q rr in + (res, c' - c). Hint Rewrite eval_cons eval_nil using solve [auto] : push_eval. @@ -2189,6 +2267,11 @@ Module Rows. fst (mul base n m p q) = partition m (Positional.eval weight n p * Positional.eval weight n q). Proof using wprops. solver. Qed. + Lemma mul_div base n m p q : + base <> 0 -> n <> 0%nat -> m <> 0%nat -> length p = n -> length q = n -> + snd (mul base n m p q) = (Positional.eval weight n p * Positional.eval weight n q) / weight m. + Proof using wprops. solver. Qed. + Lemma length_mul base n m p q : length p = n -> length q = n -> length (fst (mul base n m p q)) = m. @@ -2227,11 +2310,53 @@ Module Rows. rewrite <-Z.div_mod'' by auto. autorewrite with push_eval; reflexivity. Qed. + + (* returns all-but-lowest-limb and lowest limb *) + Definition divmod (p : list Z) : list Z * Z + := (tl p, hd 0 p). + (* + Lemma eval_divmod n (p : list Z) : + length p = S n -> + (forall i, weight i = weight 1 ^ Z.of_nat i) -> + (forall i, (i <= n)%nat -> + nth_default 0 p i = (Positional.eval weight (S n) p mod weight (S i)) / (weight i)) -> + let pv := Positional.eval weight (S n) p in + Positional.eval (fun i => weight (S i) / weight 1) n (fst (divmod p)) = pv / weight 1 + /\ snd (divmod p) = pv mod weight 1. + Proof. + cbv [is_div_mod divmod]; destruct p; cbn [fst snd hd tl length]; [ omega | ]. + intros Hlen Hsmall. + split. + { rewrite Positional.eval_cons, weight_0 by (assumption || omega). + autorewrite with zsimplify_const. + symmetry; erewrite Positional.eval_weight_mul. + Print Positional. + 2: { + (etransitivity; [ exact (Hsmall 0%nat ltac:(omega)) | ]). + rewrite weight_0 by assumption; autorewrite with zsimplify_const; reflexivity. + } + + + revert H0. + push_Zmod. +hd 0 p). + Lemma eval_divmod n (p : list Z) : + length p = S n -> p = partition (S n) (Positional.eval weight (S n) p) -> + is_div_mod (Positional.eval (fun i => weight (S i) / weight 1) n) + (divmod p) + (Positional.eval weight (S n) p) + (weight 1). + Proof. + cbv [is_div_mod divmod]; destruct p; cbn [fst snd hd tl length]; [ omega | ]. + intros. + rewrite eval_ + *) End Ops. End Rows. Hint Rewrite length_from_columns using eassumption : distr_length. Hint Rewrite length_sum_rows using solve [ reflexivity | eassumption | distr_length; eauto ] : distr_length. Hint Rewrite length_fst_extract_row length_snd_extract_row length_flatten length_flatten' length_partition length_fst_from_columns' length_snd_from_columns' : distr_length. + Hint Rewrite @eval_partition : push_eval. End Rows. Module BaseConversion. @@ -2609,7 +2734,7 @@ Section freeze_mod_ops. (m_enc_correct : Positional.eval weight n m_enc = m) (Hm_enc_len : length m_enc = n). - Definition wprops_bytes := (@wprops 8 1 ltac:(lia)). + Definition wprops_bytes := (@wprops 8 1 ltac:(clear; lia)). Local Notation wprops := (@wprops limbwidth_num limbwidth_den limbwidth_good). Local Hint Immediate (wprops). @@ -2624,7 +2749,9 @@ Section freeze_mod_ops. Local Hint Immediate (weight_divides wprops_bytes). Local Hint Resolve Z.positive_is_nonzero Z.lt_gt. - Definition bytes_n := (1 + (Z.to_nat (Z.log2_up (weight n) / 8)))%nat. + Definition bytes_n + := Eval cbv [Qceiling Qdiv inject_Z Qfloor Qmult Qopp Qnum Qden Qinv Pos.mul] + in Z.to_nat (Qceiling (Z.log2_up (weight n) / 8)). Definition to_bytes' (v : list Z) := BaseConversion.convert_bases weight bytes_weight n bytes_n v. @@ -2638,54 +2765,118 @@ Section freeze_mod_ops. that the result partitions. See https://github.com/JasonGross/fiat-crypto/tree/zzz-wip-better-arith-proofs for some partial work in this direction. *) - Definition to_bytesmod (f : list Z) : list Z - := let v := to_bytes' (freeze weight n (Z.ones bitwidth) m_enc f) in + Definition to_bytes (f : list Z) : list Z + := let v := to_bytes' f in fst (Rows.flatten bytes_weight bytes_n (Rows.from_associational bytes_weight bytes_n (Positional.to_associational bytes_weight bytes_n v))). + Definition freeze_to_bytesmod (f : list Z) : list Z + := to_bytes (freeze weight n (Z.ones bitwidth) m_enc f). + + Definition to_bytesmod (f : list Z) : list Z + := to_bytes f. + Definition from_bytesmod (f : list Z) : list Z := from_bytes f. + Lemma bytes_nz : bytes_n <> 0%nat. + Proof using limbwidth_good Hn_nz. + clear -limbwidth_good Hn_nz. + cbv [bytes_n]. + cbv [Qceiling Qdiv inject_Z Qfloor Qmult Qopp Qnum Qden Qinv]. + autorewrite with zsimplify_const. + change (Z.pos (1*8)) with 8. + cbv [weight]. + rewrite Z.log2_up_pow2 by (Z.div_mod_to_quot_rem; nia). + autorewrite with zsimplify_fast. + rewrite <- Z2Nat.inj_0, Z2Nat.inj_iff by (Z.div_mod_to_quot_rem; nia). + Z.div_mod_to_quot_rem; nia. + Qed. + + Lemma bytes_n_big : weight n <= bytes_weight bytes_n. + Proof using limbwidth_good Hn_nz. + clear -limbwidth_good Hn_nz. + cbv [bytes_n bytes_weight]. + Z.peel_le. + rewrite Z.log2_up_pow2 by (Z.div_mod_to_quot_rem; nia). + autorewrite with zsimplify_fast. + rewrite Z2Nat.id by (Z.div_mod_to_quot_rem; nia). + Z.div_mod_to_quot_rem; nia. + Qed. + + Lemma eval_to_bytes_mod + : forall (f : list Z) + (Hf : length f = n), + eval bytes_weight bytes_n (to_bytes f) = eval weight n f mod (bytes_weight bytes_n). + Proof using limbwidth_good Hn_nz. + generalize wprops wprops_bytes; clear -Hn_nz limbwidth_good. + intros. + cbv [to_bytes]. + rewrite Rows.flatten_mod by eauto using Rows.length_from_associational. + rewrite Rows.eval_from_associational by eauto using bytes_nz with omega. + rewrite eval_to_associational. + cbv [to_bytes']. + rewrite BaseConversion.eval_convert_bases + by (auto using bytes_nz; distr_length; auto using wprops). + reflexivity. + Qed. + + Lemma eval_to_bytes + : forall (f : list Z) + (Hf : length f = n) + (Hf_small : 0 <= eval weight n f < weight n), + eval bytes_weight bytes_n (to_bytes f) = eval weight n f. + Proof using Hn_nz limbwidth_good. + generalize bytes_n_big. clear -Hn_nz limbwidth_good. + intros; rewrite eval_to_bytes_mod by assumption. + rewrite Z.mod_small by omega; reflexivity. + Qed. + + Lemma to_bytes_partitions + : forall (f : list Z) + (Hf : length f = n), + to_bytes f = Rows.partition bytes_weight bytes_n (Positional.eval weight n f). + Proof using Hn_nz limbwidth_good. + clear -Hn_nz limbwidth_good. + intros; cbv [to_bytes]. + rewrite Rows.flatten_partitions' by eauto using wprops, Rows.length_from_associational. + rewrite Rows.eval_from_associational by eauto using bytes_nz with omega. + rewrite eval_to_associational. + cbv [to_bytes']. + rewrite BaseConversion.eval_convert_bases + by (auto using wprops_bytes, bytes_nz; distr_length; auto using wprops). + reflexivity. + Qed. + Lemma eval_to_bytesmod + : forall (f : list Z) + (Hf : length f = n) + (Hf_small : 0 <= eval weight n f < weight n), + eval bytes_weight bytes_n (to_bytesmod f) = eval weight n f + /\ to_bytesmod f = Rows.partition bytes_weight bytes_n (Positional.eval weight n f). + Proof using Hn_nz limbwidth_good. + split; apply eval_to_bytes || apply to_bytes_partitions; assumption. + Qed. + + Lemma eval_freeze_to_bytesmod : forall (f : list Z) (Hf : length f = n) (Hf_bounded : 0 <= eval weight n f < 2 * m), - (eval bytes_weight bytes_n (to_bytesmod f)) = (eval weight n f) mod m - /\ to_bytesmod f = Rows.partition bytes_weight bytes_n (Positional.eval weight n f mod m). + (eval bytes_weight bytes_n (freeze_to_bytesmod f)) = (eval weight n f) mod m + /\ freeze_to_bytesmod f = Rows.partition bytes_weight bytes_n (Positional.eval weight n f mod m). Proof. - intros; subst m s; split. - { cbv [to_bytesmod]. - rewrite Rows.flatten_mod by eauto using Rows.length_from_associational. - rewrite Rows.eval_from_associational by (cbv [bytes_n]; eauto with omega). - rewrite eval_to_associational. - cbv [to_bytes']. - rewrite BaseConversion.eval_convert_bases - by (cbv [bytes_n]; auto using wprops_bytes; distr_length; auto using wprops). - erewrite eval_freeze by eauto using wprops. - rewrite (Z.mod_small (_ mod _)); [ reflexivity | ]. - split; [ | eapply Z.lt_le_trans ]; [ apply Z.mod_pos_bound; omega.. | ]. - transitivity (weight n); [ omega | ]. - cbv [weight bytes_n]. - Z.peel_le. - rewrite Z.log2_up_pow2 by (Z.div_mod_to_quot_rem_in_goal; nia). - autorewrite with push_Zof_nat. - rewrite Z2Nat.id by (Z.div_mod_to_quot_rem_in_goal; nia). - Z.div_mod_to_quot_rem_in_goal; nia. } - { cbv [to_bytesmod]. - rewrite Rows.flatten_partitions' by eauto using wprops, Rows.length_from_associational. - rewrite Rows.eval_from_associational by (cbv [bytes_n]; eauto with omega). - rewrite eval_to_associational. - cbv [to_bytes']. - rewrite BaseConversion.eval_convert_bases - by (cbv [bytes_n]; auto using wprops_bytes; distr_length; auto using wprops). - erewrite eval_freeze by eauto using wprops. - reflexivity. } + intros; subst m s. + cbv [freeze_to_bytesmod]. + rewrite eval_to_bytes, to_bytes_partitions; + erewrite ?eval_freeze by eauto using wprops; + autorewrite with distr_length; eauto. + Z.div_mod_to_quot_rem; nia. Qed. Lemma eval_from_bytesmod : forall (f : list Z) (Hf : length f = bytes_n), eval weight n (from_bytesmod f) = eval bytes_weight bytes_n f. - Proof. + Proof using Hn_nz limbwidth_good. cbv [from_bytesmod from_bytes]; intros. rewrite BaseConversion.eval_convert_bases by eauto using wprops. reflexivity. @@ -2729,3 +2920,1053 @@ Section primitives. | progress Z.rewrite_mod_small ]. Qed. End primitives. + +Module UniformWeight. + Definition uweight (lgr : Z) : nat -> Z + := weight lgr 1. + Definition uwprops lgr (Hr : 0 < lgr) : @weight_properties (uweight lgr). + Proof. apply wprops; omega. Qed. + Lemma uweight_eq_alt' lgr n : uweight lgr n = 2^(lgr*Z.of_nat n). + Proof. now cbv [uweight weight]; autorewrite with zsimplify_fast. Qed. + Lemma uweight_eq_alt lgr (Hr : 0 <= lgr) n : uweight lgr n = (2^lgr)^Z.of_nat n. + Proof. now rewrite uweight_eq_alt', Z.pow_mul_r by lia. Qed. +End UniformWeight. + +Module WordByWordMontgomery. + Section with_args. + Context (lgr : Z) + (m : Z). + Local Notation weight := (UniformWeight.uweight lgr). + Let T (n : nat) := list Z. + Let r := (2^lgr). + Definition eval {n} : T n -> Z := Positional.eval weight n. + Let zero {n} : T n := Positional.zeros n. + Let divmod {n} : T (S n) -> T n * Z := Rows.divmod. + Let scmul {n} (c : Z) (p : T n) : T (S n) (* uses double-output multiply *) + := let '(v, c) := Rows.mul weight r n (S n) (Positional.extend_to_length 1 n [c]) p in + v. + Let addT {n} (p q : T n) : T (S n) (* joins carry *) + := let '(v, c) := Rows.add weight n p q in + v ++ [c]. + Let drop_high_addT' {n} (p : T (S n)) (q : T n) : T (S n) (* drops carry *) + := fst (Rows.add weight (S n) p (Positional.extend_to_length n (S n) q)). + Let conditional_sub {n} (arg : T (S n)) (N : T n) : T n (* computes [arg - N] if [N <= arg], and drops high bit *) + := Positional.drop_high_to_length n (Rows.conditional_sub weight (S n) arg (Positional.extend_to_length n (S n) N)). + Context (R_numlimbs : nat) + (N : T R_numlimbs). (* encoding of m *) + Let sub_then_maybe_add (a b : T R_numlimbs) : T R_numlimbs (* computes [a - b + if (a - b) T pred_A_numlimbs * T (S R_numlimbs) + := fun '(A, S') => A'_S3 _ B k A S'. + + Definition redc_loop (count : nat) : T count * T (S R_numlimbs) -> T O * T (S R_numlimbs) + := nat_rect + (fun count => T count * _ -> _) + (fun A_S => A_S) + (fun count' redc_loop_count' A_S + => redc_loop_count' (redc_body A_S)) + count. + + Definition pre_redc : T (S R_numlimbs) + := snd (redc_loop A_numlimbs (A, @zero (1 + R_numlimbs)%nat)). + + Definition redc : T R_numlimbs + := conditional_sub pre_redc N. + End loop. + + Create HintDb word_by_word_montgomery. + Hint Unfold A'_S3 S3' S2 q s S1 a A' A_a Let_In : word_by_word_montgomery. + + Definition add (A B : T R_numlimbs) : T R_numlimbs + := conditional_sub (@addT _ A B) N. + Definition sub (A B : T R_numlimbs) : T R_numlimbs + := sub_then_maybe_add A B. + Definition opp (A : T R_numlimbs) : T R_numlimbs + := sub (@zero _) A. + Definition nonzero (A : list Z) : Z + := fold_right Z.lor 0 A. + + Context (lgr_big : 0 < lgr) + (R_numlimbs_nz : R_numlimbs <> 0%nat). + Let R := (r^Z.of_nat R_numlimbs). + Transparent T. + Definition small {n} (v : T n) : Prop + := v = Rows.partition weight n (eval v). + Context (small_N : small N) + (N_lt_R : eval N < R) + (N_nz : 0 < eval N) + (B : T R_numlimbs) + (B_bounds : 0 <= eval B < R) + (small_B : small B) + ri (ri_correct : r*ri mod (eval N) = 1 mod (eval N)) + (k : Z) (k_correct : k * eval N mod r = (-1) mod r). + + Local Lemma r_big : r > 1. + Proof using lgr_big. clear -lgr_big; subst r. auto with zarith. Qed. + Local Notation wprops := (@UniformWeight.uwprops lgr lgr_big). + + Local Hint Immediate (wprops). + Local Hint Immediate (weight_0 wprops). + Local Hint Immediate (weight_positive wprops). + Local Hint Immediate (weight_multiples wprops). + Local Hint Immediate (weight_divides wprops). + Local Hint Immediate r_big. + + Lemma length_small {n v} : @small n v -> length v = n. + Proof using Type. clear; cbv [small]; intro H; rewrite H; autorewrite with distr_length; reflexivity. Qed. + + Let partition_Proper := (@Rows.partition_Proper _ wprops). + Local Existing Instance partition_Proper. + Lemma eval_nonzero n A : @small n A -> nonzero A = 0 <-> @eval n A = 0. + Proof. + cbv [nonzero eval small]; intro Heq. + do 2 rewrite Heq. + rewrite !Rows.eval_partition, Z.mod_mod by auto. + generalize (Positional.eval weight n A); clear Heq A. + induction n as [|n IHn]. + { cbn; rewrite weight_0 by auto; intros; autorewrite with zsimplify_const; omega. } + { intro; rewrite Rows.partition_step. + rewrite fold_right_snoc, Z.lor_comm, <- fold_right_push, Z.lor_eq_0_iff by auto using Z.lor_assoc. + assert (Heq : Z.equiv_modulo (weight n) (z mod weight (S n)) (z mod (weight n))). + { cbv [Z.equiv_modulo]. + generalize (weight_multiples ltac:(auto) n). + generalize (weight_positive ltac:(auto) n). + generalize (weight_positive ltac:(auto) (S n)). + generalize (weight (S n)) (weight n); clear; intros wsn wn. + clear; intros. + Z.div_mod_to_quot_rem; subst. + autorewrite with zsimplify_const in *. + Z.linear_substitute_all. + apply Zminus_eq; ring_simplify. + rewrite <- !Z.add_opp_r, !Z.mul_opp_comm, <- !Z.mul_opp_r, <- !Z.mul_assoc. + rewrite <- !Z.mul_add_distr_l, Z.mul_eq_0. + nia. } + rewrite Heq at 1; rewrite IHn. + rewrite Z.mod_mod by auto. + generalize (weight_multiples ltac:(auto) n). + generalize (weight_positive ltac:(auto) n). + generalize (weight_positive ltac:(auto) (S n)). + generalize (weight (S n)) (weight n); clear; intros wsn wn; intros. + Z.div_mod_to_quot_rem. + repeat (intro || apply conj); destruct_head'_or; try omega; destruct_head'_and; subst; autorewrite with zsimplify_const in *; try nia; + Z.linear_substitute_all. + all: apply Zminus_eq; ring_simplify. + all: rewrite <- ?Z.add_opp_r, ?Z.mul_opp_comm, <- ?Z.mul_opp_r, <- ?Z.mul_assoc. + all: rewrite <- !Z.mul_add_distr_l, Z.mul_eq_0. + all: nia. } + Qed. + + Local Ltac push_step := + first [ progress eta_expand + | rewrite Rows.mul_partitions + | rewrite Rows.mul_div + | rewrite Rows.add_partitions + | rewrite Rows.add_div + | progress autorewrite with push_eval distr_length + | match goal with + | [ H : ?v = _ |- context[length ?v] ] => erewrite length_small by eassumption + | [ H : small ?v |- context[length ?v] ] => erewrite length_small by eassumption + end + | rewrite Positional.eval_cons + | rewrite (weight_0 wprops) + | rewrite <- Z.div_mod'' by auto with omega + | solve [ trivial ] ]. + Local Ltac push := repeat push_step. + + Local Ltac t_step := + match goal with + | [ H := _ |- _ ] => progress cbv [H] in * + | _ => progress push_step + | _ => progress autorewrite with zsimplify_const + | _ => solve [ auto with omega ] + end. + + Local Hint Unfold eval zero small divmod scmul drop_high_addT' addT R : loc. + Local Lemma eval_zero : forall n, eval (@zero n) = 0. + Proof using Type. + clear; autounfold with loc; intros; autorewrite with push_eval; auto. + cbv -[Z.pow Z.mul Z.opp Z.div]; autorewrite with zsimplify_const; reflexivity. + Qed. + Local Lemma small_zero : forall n, small (@zero n). + Proof using Type. + etransitivity; [ eapply Positional.zeros_ext_map | rewrite eval_zero ]; cbv [Rows.partition]; cbn; try reflexivity; autorewrite with distr_length; reflexivity. + Qed. + Local Hint Immediate small_zero. + Local Axiom eval_div : forall n v, small v -> eval (fst (@divmod n v)) = eval v / r. + Local Axiom eval_mod : forall n v, small v -> snd (@divmod n v) = eval v mod r. + Local Axiom small_div : forall n v, small v -> small (fst (@divmod n v)). + Local Lemma eval_scmul: forall n a v, small v -> 0 <= a < r -> 0 <= eval v < r^Z.of_nat n -> eval (@scmul n a v) = a * eval v. + Proof using lgr_big. + generalize (@length_small); clear -lgr_big; intro. + autounfold with loc; intro n; destruct (zerop n). + { cbn; intros; subst; cbn; rewrite Z.add_with_get_carry_full_mod; cbn; omega. } + intros; repeat t_step. + repeat first [ reflexivity + | rewrite UniformWeight.uweight_eq_alt by omega + | progress autorewrite with push_Zof_nat + | rewrite Z.pow_succ_r by lia + | progress Z.rewrite_mod_small ]. + Qed. + Local Lemma small_scmul : forall n a v, small v -> 0 <= a < r -> 0 <= eval v < r^Z.of_nat n -> small (@scmul n a v). + Proof using lgr_big. + intros n a v Hpart. + generalize (length_small Hpart). + generalize eval_scmul. + clear -Hpart lgr_big. + destruct (zerop n). + { destruct v; subst; cbn; try congruence; cbv [small]; cbn. + rewrite Z.add_with_get_carry_full_mod; cbn; autorewrite with zsimplify_const; reflexivity. } + { cbv [small]; intros eval_scmul; intros. + rewrite eval_scmul by auto. + cbv [scmul]; eta_expand. + rewrite Rows.mul_partitions by (auto with omega; autorewrite with distr_length; auto with omega). + autorewrite with push_eval; auto with omega. + rewrite Positional.eval_cons, Positional.eval_nil by reflexivity. + rewrite weight_0 by auto; autorewrite with zsimplify_const; reflexivity. } + Qed. + Local Lemma eval_addT : forall n a b, small a -> small b -> eval (@addT n a b) = eval a + eval b. + Proof using lgr_big. + intros n a b Ha Hb; generalize (length_small Ha); generalize (length_small Hb). + clear -lgr_big Ha Hb. + autounfold with loc; destruct (zerop n); subst. + { destruct a, b; cbn; try omega. } + { eta_expand; intros; repeat t_step. } + Qed. + Local Axiom small_addT : forall n a b, small a -> small b -> small (@addT n a b). + Local Lemma eval_drop_high_addT' : forall n a b, small a -> small b -> eval (@drop_high_addT' n a b) = (eval a + eval b) mod (r^Z.of_nat (S n)). + Proof using lgr_big. + intros n a b Ha Hb; generalize (length_small Ha); generalize (length_small Hb). + clear -lgr_big Ha Hb. + autounfold with loc in *; destruct (zerop n); subst. + { destruct a as [| ? [|] ], b; cbn; try omega. + cbv [Rows.partition seq eval map] in Ha. + cbn in Ha. + rewrite (weight_0 wprops) in *. + rewrite Z.add_with_get_carry_full_mod. + subst r. + rewrite UniformWeight.uweight_eq_alt in * by omega. + autorewrite with zsimplify_const in *. + inversion Ha as [Ha']; clear Ha. + rewrite <- !Ha'. + reflexivity. } + { eta_expand; intros; repeat t_step. + rewrite UniformWeight.uweight_eq_alt by omega. + reflexivity. } + Qed. + Local Lemma small_drop_high_addT' : forall n a b, small a -> small b -> small (@drop_high_addT' n a b). + Proof using lgr_big. + intros n a b Ha Hb; generalize (length_small Ha); generalize (length_small Hb); generalize (@eval_drop_high_addT' n a b Ha). + clear -lgr_big Ha Hb. + cbv [small]. + intro Heq; rewrite Heq; autounfold with loc in *. + rewrite Ha, Hb. + repeat t_step. + rewrite !UniformWeight.uweight_eq_alt by omega. + autorewrite with push_Zof_nat zsimplify_fast. + rewrite Z.pow_succ_r by omega. + Admitted. + Local Axiom eval_conditional_sub : forall v, small v -> 0 <= eval v < eval N + R -> eval (conditional_sub v N) = eval v + if eval N <=? eval v then -eval N else 0. + Local Axiom small_conditional_sub : forall v, small v -> 0 <= eval v < eval N + R -> small (conditional_sub v N). + Local Axiom eval_sub_then_maybe_add : forall a b, small a -> small b -> 0 <= eval a < eval N -> 0 <= eval b < eval N -> eval (sub_then_maybe_add a b) = eval a - eval b + if eval a - eval b destruct H + end ]. + Hint Rewrite + eval_zero + eval_div + eval_mod + eval_addT + eval_drop_high_addT' + eval_scmul + eval_conditional_sub + eval_sub_then_maybe_add + using (repeat autounfold with word_by_word_montgomery; t_small) + : push_mont_eval. + + Local Arguments eval {_} _. + Local Arguments small {_} _. + Local Arguments divmod {_} _. + + (* Recurse for a as many iterations as A has limbs, varying A := A, S := 0, r, bounds *) + Section Iteration_proofs. + Context (pred_A_numlimbs : nat) + (A : T (S pred_A_numlimbs)) + (S : T (S R_numlimbs)) + (small_A : small A) + (small_S : small S) + (S_nonneg : 0 <= eval S). + (* Given A, B < R, we want to compute A * B / R mod N. R = bound 0 * ... * bound (n-1) *) + + Local Coercion eval : T >-> Z. + + Local Notation a := (@a pred_A_numlimbs A). + Local Notation A' := (@A' pred_A_numlimbs A). + Local Notation S1 := (@S1 pred_A_numlimbs B A S). + Local Notation s := (@s pred_A_numlimbs B A S). + Local Notation q := (@q pred_A_numlimbs B k A S). + Local Notation S2 := (@S2 pred_A_numlimbs B k A S). + Local Notation S3 := (@S3' pred_A_numlimbs B k A S). + + Local Notation eval_pre_S3 := ((S + a * B + q * N) / r). + + Lemma eval_S3_eq : eval S3 = eval_pre_S3 mod (r * r ^ Z.of_nat R_numlimbs). + Proof. + unfold S3, S2, S1. + autorewrite with push_mont_eval push_Zof_nat; []. + rewrite !Z.pow_succ_r, <- ?Z.mul_assoc by omega. + rewrite Z.mod_pull_div by Z.zero_bounds. + do 2 f_equal; nia. + Qed. + + Lemma pre_S3_bound + : eval S < eval N + eval B + -> eval_pre_S3 < eval N + eval B. + Proof. + assert (Hmod : forall a b, 0 < b -> a mod b <= b - 1) + by (intros x y; pose proof (Z_mod_lt x y); omega). + intro HS. + eapply Z.le_lt_trans. + { transitivity ((N+B-1 + (r-1)*B + (r-1)*N) / r); + [ | set_evars; ring_simplify_subterms; subst_evars; reflexivity ]. + Z.peel_le; repeat apply Z.add_le_mono; repeat apply Z.mul_le_mono_nonneg; try lia; + repeat autounfold with word_by_word_montgomery; rewrite ?Z.mul_split_mod; + autorewrite with push_mont_eval; + try Z.zero_bounds; + auto with lia. } + rewrite (Z.mul_comm _ r), <- Z.add_sub_assoc, <- Z.add_opp_r, !Z.div_add_l' by lia. + autorewrite with zsimplify. + simpl; omega. + Qed. + + Lemma pre_S3_nonneg : 0 <= eval_pre_S3. + Proof. + repeat autounfold with word_by_word_montgomery; rewrite ?Z.mul_split_mod; + autorewrite with push_mont_eval; []. + rewrite ?Npos_correct; Z.zero_bounds; lia. + Qed. + + Lemma small_A' + : small A'. + Proof. repeat autounfold with word_by_word_montgomery; t_small. Qed. + + Lemma small_S3 + : small S3. + Proof. repeat autounfold with word_by_word_montgomery; t_small. Qed. + + Lemma S3_nonneg : 0 <= eval S3. + Proof. rewrite eval_S3_eq; Z.zero_bounds. Qed. + + Lemma S3_bound + : eval S < eval N + eval B + -> eval S3 < eval N + eval B. + Proof. + rewrite eval_S3_eq. + intro H; pose proof (pre_S3_bound H); pose proof pre_S3_nonneg. + subst R. + rewrite Z.mod_small by nia. + assumption. + Qed. + + Lemma S1_eq : eval S1 = S + a*B. + Proof. + cbv [S1 a A']. + repeat autorewrite with push_mont_eval. + reflexivity. + Qed. + + Lemma S2_mod_r_helper : (S + a*B + q * N) mod r = 0. + Proof. + cbv [S2 q s]; autorewrite with push_mont_eval; rewrite S1_eq. + assert (r > 0) by lia. + assert (Hr : (-(1 mod r)) mod r = r - 1 /\ (-(1)) mod r = r - 1). + { destruct (Z.eq_dec r 1) as [H'|H']. + { rewrite H'; split; reflexivity. } + { rewrite !Z_mod_nz_opp_full; rewrite ?Z.mod_mod; Z.rewrite_mod_small; [ split; reflexivity | omega.. ]. } } + autorewrite with pull_Zmod. + replace 0 with (0 mod r) by apply Zmod_0_l. + pose (Z.to_pos r) as r'. + replace r with (Z.pos r') by (subst r'; rewrite Z2Pos.id; lia). + eapply F.eq_of_Z_iff. + rewrite Z.mul_split_mod. + repeat rewrite ?F.of_Z_add, ?F.of_Z_mul, <-?F.of_Z_mod. + rewrite <-!Algebra.Hierarchy.associative. + replace ((F.of_Z r' k * F.of_Z r' (eval N))%F) with (F.opp (m:=r') F.one). + { cbv [F.of_Z F.add]; simpl. + apply path_sig_hprop; [ intro; exact HProp.allpath_hprop | ]. + simpl. + subst r'; rewrite Z2Pos.id by lia. + rewrite (proj1 Hr), Z.mul_sub_distr_l. + push_Zmod; pull_Zmod. + apply (f_equal2 Z.modulo); omega. } + { rewrite <- F.of_Z_mul. + rewrite F.of_Z_mod. + subst r'; rewrite Z2Pos.id by lia. + rewrite k_correct. + cbv [F.of_Z F.add F.opp F.one]; simpl. + change (-(1)) with (-1) in *. + apply path_sig_hprop; [ intro; exact HProp.allpath_hprop | ]; simpl. + rewrite Z2Pos.id by lia. + rewrite (proj1 Hr), (proj2 Hr); Z.rewrite_mod_small; reflexivity. } + Qed. + + Lemma pre_S3_mod_N + : eval_pre_S3 mod N = (S + a*B)*ri mod N. + Proof. + pose proof fun a => Z.div_to_inv_modulo N a r ri ltac:(lia) ri_correct as HH; + cbv [Z.equiv_modulo] in HH; rewrite HH; clear HH. + etransitivity; [rewrite (fun a => Z.mul_mod_l a ri N)| + rewrite (fun a => Z.mul_mod_l a ri N); reflexivity]. + rewrite S2_mod_r_helper. + push_Zmod; pull_Zmod; autorewrite with zsimplify_const. + reflexivity. + Qed. + + Lemma S3_mod_N + (Hbound : eval S < eval N + eval B) + : S3 mod N = (S + a*B)*ri mod N. + Proof. + rewrite eval_S3_eq. + pose proof (pre_S3_bound Hbound); pose proof pre_S3_nonneg. + rewrite (Z.mod_small _ (r * _)) by (subst R; nia). + apply pre_S3_mod_N. + Qed. + End Iteration_proofs. + + Section redc_proofs. + Local Notation redc_body := (@redc_body B k). + Local Notation redc_loop := (@redc_loop B k). + Local Notation pre_redc A := (@pre_redc _ A B k). + Local Notation redc A := (@redc _ A B k). + + Section body. + Context (pred_A_numlimbs : nat) + (A_S : T (S pred_A_numlimbs) * T (S R_numlimbs)). + Let A:=fst A_S. + Let S:=snd A_S. + Let A_a:=divmod A. + Let a:=snd A_a. + Context (small_A : small A) + (small_S : small S) + (S_bound : 0 <= eval S < eval N + eval B). + + Lemma small_fst_redc_body : small (fst (redc_body A_S)). + Proof. destruct A_S; apply small_A'; assumption. Qed. + Lemma small_snd_redc_body : small (snd (redc_body A_S)). + Proof. destruct A_S; unfold redc_body; apply small_S3; assumption. Qed. + Lemma snd_redc_body_nonneg : 0 <= eval (snd (redc_body A_S)). + Proof. destruct A_S; apply S3_nonneg; assumption. Qed. + + Lemma snd_redc_body_mod_N + : (eval (snd (redc_body A_S))) mod (eval N) = (eval S + a*eval B)*ri mod (eval N). + Proof. destruct A_S; apply S3_mod_N; auto; omega. Qed. + + Lemma fst_redc_body + : (eval (fst (redc_body A_S))) = eval (fst A_S) / r. + Proof. + destruct A_S; simpl; repeat autounfold with word_by_word_montgomery; simpl. + autorewrite with push_mont_eval. + reflexivity. + Qed. + + Lemma fst_redc_body_mod_N + : (eval (fst (redc_body A_S))) mod (eval N) = ((eval (fst A_S) - a)*ri) mod (eval N). + Proof. + rewrite fst_redc_body. + etransitivity; [ eapply Z.div_to_inv_modulo; try eassumption; lia | ]. + unfold a, A_a, A. + autorewrite with push_mont_eval. + reflexivity. + Qed. + + Lemma redc_body_bound + : eval S < eval N + eval B + -> eval (snd (redc_body A_S)) < eval N + eval B. + Proof. + destruct A_S; apply S3_bound; unfold S in *; cbn [snd] in *; try assumption; try omega. + Qed. + End body. + + Local Arguments Z.pow !_ !_. + Local Arguments Z.of_nat !_. + Local Ltac induction_loop count IHcount + := induction count as [|count IHcount]; intros; cbn [redc_loop nat_rect] in *; [ | (*rewrite redc_loop_comm_body in * *) ]. + Lemma redc_loop_good count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : (small (fst (redc_loop count A_S)) /\ small (snd (redc_loop count A_S))) + /\ 0 <= eval (snd (redc_loop count A_S)) < eval N + eval B. + Proof. + induction_loop count IHcount; auto; []. + change (id (0 <= eval B < R)) in B_bounds (* don't let [destruct_head'_and] loop *). + destruct_head'_and. + repeat first [ apply conj + | apply small_fst_redc_body + | apply small_snd_redc_body + | apply redc_body_bound + | apply snd_redc_body_nonneg + | apply IHcount + | solve [ auto ] ]. + Qed. + + Lemma small_redc_loop count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : small (fst (redc_loop count A_S)) /\ small (snd (redc_loop count A_S)). + Proof. apply redc_loop_good; assumption. Qed. + + Lemma redc_loop_bound count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : 0 <= eval (snd (redc_loop count A_S)) < eval N + eval B. + Proof. apply redc_loop_good; assumption. Qed. + + Local Ltac handle_IH_small := + repeat first [ apply redc_loop_good + | apply small_fst_redc_body + | apply small_snd_redc_body + | apply redc_body_bound + | apply snd_redc_body_nonneg + | apply conj + | progress cbn [fst snd] + | progress destruct_head' and + | solve [ auto ] ]. + + Lemma fst_redc_loop count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : eval (fst (redc_loop count A_S)) = eval (fst A_S) / r^(Z.of_nat count). + Proof. + cbv [redc_loop]; induction_loop count IHcount. + { simpl; autorewrite with zsimplify; reflexivity. } + { rewrite IHcount, fst_redc_body by handle_IH_small. + change (1 + R_numlimbs)%nat with (S R_numlimbs) in *. + rewrite Zdiv_Zdiv by Z.zero_bounds. + rewrite <- (Z.pow_1_r r) at 1. + rewrite <- Z.pow_add_r by lia. + replace (1 + Z.of_nat count) with (Z.of_nat (S count)) by lia. + reflexivity. } + Qed. + + Lemma fst_redc_loop_mod_N count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : eval (fst (redc_loop count A_S)) mod (eval N) + = (eval (fst A_S) - eval (fst A_S) mod r^Z.of_nat count) + * ri^(Z.of_nat count) mod (eval N). + Proof. + rewrite fst_redc_loop by assumption. + destruct count. + { simpl; autorewrite with zsimplify; reflexivity. } + { etransitivity; + [ eapply Z.div_to_inv_modulo; + try solve [ eassumption + | apply Z.lt_gt, Z.pow_pos_nonneg; lia ] + | ]. + { erewrite <- Z.pow_mul_l, <- Z.pow_1_l. + { apply Z.pow_mod_Proper; [ eassumption | reflexivity ]. } + { lia. } } + reflexivity. } + Qed. + + Local Arguments Z.pow : simpl never. + Lemma snd_redc_loop_mod_N count A_S + (Hsmall : small (fst A_S) /\ small (snd A_S)) + (Hbound : 0 <= eval (snd A_S) < eval N + eval B) + : (eval (snd (redc_loop count A_S))) mod (eval N) + = ((eval (snd A_S) + (eval (fst A_S) mod r^(Z.of_nat count))*eval B)*ri^(Z.of_nat count)) mod (eval N). + Proof. + cbv [redc_loop]. + induction_loop count IHcount. + { simpl; autorewrite with zsimplify; reflexivity. } + { rewrite IHcount by handle_IH_small. + push_Zmod; rewrite snd_redc_body_mod_N, fst_redc_body by handle_IH_small; pull_Zmod. + autorewrite with push_mont_eval; []. + match goal with + | [ |- ?x mod ?N = ?y mod ?N ] + => change (Z.equiv_modulo N x y) + end. + destruct A_S as [A S]. + cbn [fst snd]. + change (Z.pos (Pos.of_succ_nat ?n)) with (Z.of_nat (Datatypes.S n)). + rewrite !Z.mul_add_distr_r. + rewrite <- !Z.mul_assoc. + replace (ri * ri^(Z.of_nat count)) with (ri^(Z.of_nat (Datatypes.S count))) + by (change (Datatypes.S count) with (1 + count)%nat; + autorewrite with push_Zof_nat; rewrite Z.pow_add_r by lia; simpl Z.succ; rewrite Z.pow_1_r; nia). + rewrite <- !Z.add_assoc. + apply Z.add_mod_Proper; [ reflexivity | ]. + unfold Z.equiv_modulo; push_Zmod; rewrite (Z.mul_mod_l (_ mod r) _ (eval N)). + rewrite Z.mod_pull_div by auto with zarith lia. + push_Zmod. + erewrite Z.div_to_inv_modulo; + [ + | apply Z.lt_gt; lia + | eassumption ]. + pull_Zmod. + match goal with + | [ |- ?x mod ?N = ?y mod ?N ] + => change (Z.equiv_modulo N x y) + end. + repeat first [ rewrite <- !Z.pow_succ_r, <- !Nat2Z.inj_succ by lia + | rewrite (Z.mul_comm _ ri) + | rewrite (Z.mul_assoc _ ri _) + | rewrite (Z.mul_comm _ (ri^_)) + | rewrite (Z.mul_assoc _ (ri^_) _) ]. + repeat first [ rewrite <- Z.mul_assoc + | rewrite <- Z.mul_add_distr_l + | rewrite (Z.mul_comm _ (eval B)) + | rewrite !Nat2Z.inj_succ, !Z.pow_succ_r by lia; + rewrite <- Znumtheory.Zmod_div_mod by (apply Z.divide_factor_r || Z.zero_bounds) + | rewrite Zplus_minus + | rewrite (Z.mul_comm r (r^_)) + | reflexivity ]. } + Qed. + + Lemma pre_redc_bound A_numlimbs (A : T A_numlimbs) + (small_A : small A) + : 0 <= eval (pre_redc A) < eval N + eval B. + Proof. + unfold pre_redc. + apply redc_loop_good; simpl; autorewrite with push_mont_eval; + rewrite ?Npos_correct; auto; lia. + Qed. + + Lemma small_pre_redc A_numlimbs (A : T A_numlimbs) + (small_A : small A) + : small (pre_redc A). + Proof. + unfold pre_redc. + apply redc_loop_good; simpl; autorewrite with push_mont_eval; + rewrite ?Npos_correct; auto; lia. + Qed. + + Lemma pre_redc_mod_N A_numlimbs (A : T A_numlimbs) (small_A : small A) (A_bound : 0 <= eval A < r ^ Z.of_nat A_numlimbs) + : (eval (pre_redc A)) mod (eval N) = (eval A * eval B * ri^(Z.of_nat A_numlimbs)) mod (eval N). + Proof. + unfold pre_redc. + rewrite snd_redc_loop_mod_N; cbn [fst snd]; + autorewrite with push_mont_eval zsimplify; + [ | rewrite ?Npos_correct; auto; lia.. ]. + Z.rewrite_mod_small. + reflexivity. + Qed. + + Lemma redc_mod_N A_numlimbs (A : T A_numlimbs) (small_A : small A) (A_bound : 0 <= eval A < r ^ Z.of_nat A_numlimbs) + : (eval (redc A)) mod (eval N) = (eval A * eval B * ri^(Z.of_nat A_numlimbs)) mod (eval N). + Proof. + pose proof (@small_pre_redc _ A small_A). + pose proof (@pre_redc_bound _ A small_A). + unfold redc. + autorewrite with push_mont_eval; []. + break_innermost_match; + try rewrite Z.add_opp_r, Zminus_mod, Z_mod_same_full; + autorewrite with zsimplify_fast; + apply pre_redc_mod_N; auto. + Qed. + + Lemma redc_bound_tight A_numlimbs (A : T A_numlimbs) + (small_A : small A) + : 0 <= eval (redc A) < eval N + eval B + if eval N <=? eval (pre_redc A) then -eval N else 0. + Proof. + pose proof (@small_pre_redc _ A small_A). + pose proof (@pre_redc_bound _ A small_A). + unfold redc. + rewrite eval_conditional_sub by t_small. + break_innermost_match; Z.ltb_to_lt; omega. + Qed. + + Lemma redc_bound_N A_numlimbs (A : T A_numlimbs) + (small_A : small A) + : eval B < eval N -> 0 <= eval (redc A) < eval N. + Proof. + pose proof (@small_pre_redc _ A small_A). + pose proof (@pre_redc_bound _ A small_A). + unfold redc. + rewrite eval_conditional_sub by t_small. + break_innermost_match; Z.ltb_to_lt; omega. + Qed. + + Lemma redc_bound A_numlimbs (A : T A_numlimbs) + (small_A : small A) + (A_bound : 0 <= eval A < r ^ Z.of_nat A_numlimbs) + : 0 <= eval (redc A) < R. + Proof. + pose proof (@small_pre_redc _ A small_A). + pose proof (@pre_redc_bound _ A small_A). + unfold redc. + rewrite eval_conditional_sub by t_small. + break_innermost_match; Z.ltb_to_lt; try omega. + Qed. + + Lemma small_redc A_numlimbs (A : T A_numlimbs) + (small_A : small A) + (A_bound : 0 <= eval A < r ^ Z.of_nat A_numlimbs) + : small (redc A). + Proof. + pose proof (@small_pre_redc _ A small_A). + pose proof (@pre_redc_bound _ A small_A). + unfold redc. + apply small_conditional_sub; [ apply small_pre_redc | .. ]; auto; omega. + Qed. + End redc_proofs. + + Section add_sub. + Context (Av Bv : T R_numlimbs) + (small_Av : small Av) + (small_Bv : small Bv) + (Av_bound : 0 <= eval Av < eval N) + (Bv_bound : 0 <= eval Bv < eval N). + + Local Ltac do_clear := + clear dependent B; clear dependent k; clear dependent ri. + + Lemma small_add : small (add Av Bv). + Proof. unfold add; t_small. Qed. + Lemma small_sub : small (sub Av Bv). + Proof. unfold sub; t_small. Qed. + Lemma small_opp : small (opp Av). + Proof. unfold opp, sub; t_small. Qed. + + Lemma eval_add : eval (add Av Bv) = eval Av + eval Bv + if (eval N <=? eval Av + eval Bv) then -eval N else 0. + Proof. unfold add; autorewrite with push_mont_eval; reflexivity. Qed. + Lemma eval_sub : eval (sub Av Bv) = eval Av - eval Bv + if (eval Av - eval Bv -> Z. + Context (r' : Z) + (m' : Z) + (r'_correct : (r * r') mod m = 1) + (m'_correct : (m * m') mod r = (-1) mod r) + (bitwidth_big : 0 < bitwidth) + (m_big : 1 < m) + (n_nz : n <> 0%nat) + (m_small : m < r^n). + + Local Notation wprops := (@UniformWeight.uwprops bitwidth bitwidth_big). + Local Notation small := (@small bitwidth n). + + Local Hint Immediate (wprops). + Local Hint Immediate (weight_0 wprops). + Local Hint Immediate (weight_positive wprops). + Local Hint Immediate (weight_multiples wprops). + Local Hint Immediate (weight_divides wprops). + + Local Lemma m_enc_correct_montgomery : m = eval m_enc. + Proof. + cbv [eval m_enc]; autorewrite with push_eval; auto. + rewrite UniformWeight.uweight_eq_alt by omega. + Z.rewrite_mod_small; reflexivity. + Qed. + Local Lemma r'_pow_correct : (r'^n * r^n) mod (eval m_enc) = 1. + Proof. + rewrite <- Z.pow_mul_l, Z.mod_pow_full, ?(Z.mul_comm r'), <- m_enc_correct_montgomery, r'_correct. + autorewrite with zsimplify_const; auto with omega. + Z.rewrite_mod_small; omega. + Qed. + Local Lemma small_m_enc : small m_enc. + Proof. + cbv [m_enc small eval]; autorewrite with push_eval; auto. + rewrite UniformWeight.uweight_eq_alt by omega. + Z.rewrite_mod_small; reflexivity. + Qed. + + Local Ltac t_fin := + repeat match goal with + | _ => assumption + | [ |- ?x = ?x ] => reflexivity + | [ |- and _ _ ] => split + | _ => rewrite <- !m_enc_correct_montgomery + | _ => rewrite !r'_correct + | _ => rewrite !Z.mod_1_l by assumption; reflexivity + | _ => rewrite !(Z.mul_comm m' m) + | _ => lia + | _ => exact small_m_enc + | [ H : small ?x |- context[eval ?x] ] + => rewrite H; cbv [eval]; rewrite Rows.eval_partition by auto + | [ |- context[weight _] ] => rewrite UniformWeight.uweight_eq_alt by auto with omega + | _=> progress Z.rewrite_mod_small + | _ => progress Z.zero_bounds + | [ |- _ mod ?x < ?x ] => apply Z.mod_pos_bound + end. + + Definition mulmod (a b : list Z) : list Z := @redc bitwidth n m_enc n a b m'. + Definition squaremod (a : list Z) : list Z := mulmod a a. + Definition addmod (a b : list Z) : list Z := @add bitwidth n m_enc a b. + Definition submod (a b : list Z) : list Z := @sub bitwidth n m_enc a b. + Definition oppmod (a : list Z) : list Z := @opp bitwidth n m_enc a. + Definition nonzeromod (a : list Z) : Z := @nonzero a. + Definition to_bytesmod (a : list Z) : list Z := @to_bytesmod bitwidth 1 n a. + + Definition valid (a : list Z) := small a /\ 0 <= eval a < m. + + Lemma mulmod_correct0 + : forall a b : list Z, + small a -> small b + -> small (mulmod a b) + /\ (eval b < m -> 0 <= eval (mulmod a b) < m) + /\ (eval (mulmod a b) mod m = (eval a * eval b * r'^n) mod m). + Proof. + intros a b Ha Hb; repeat apply conj; cbv [small mulmod eval]; + [ eapply small_redc + | rewrite m_enc_correct_montgomery; eapply redc_bound_N + | rewrite !m_enc_correct_montgomery; eapply redc_mod_N ]; + t_fin. + Qed. + + Definition onemod : list Z := Rows.partition weight n 1. + + Definition onemod_correct : eval onemod = 1 /\ valid onemod. + Proof. cbv [valid small onemod eval]; autorewrite with push_eval; t_fin. Qed. + + Definition R2mod : list Z := Rows.partition weight n ((r^n * r^n) mod m). + + Definition R2mod_correct : eval R2mod mod m = (r^n*r^n) mod m /\ valid R2mod. + Proof. + cbv [valid small R2mod eval]; autorewrite with push_eval; t_fin; + rewrite !(Z.mod_small (_ mod m)) by (Z.div_mod_to_quot_rem; subst r; lia); + t_fin. + Qed. + + Definition from_montgomery_mod (v : list Z) : list Z + := mulmod v onemod. + + Lemma from_montgomery_mod_correct (v : list Z) + : valid v -> eval (from_montgomery_mod v) mod m = (eval v * r'^n) mod m + /\ valid (from_montgomery_mod v). + Proof. + intro Hv; cbv [from_montgomery_mod valid] in *; destruct_head'_and. + replace (eval v * r'^n) with (eval v * eval onemod * r'^n) by (rewrite (proj1 onemod_correct); lia). + repeat apply conj; apply mulmod_correct0; auto; try apply onemod_correct; rewrite (proj1 onemod_correct); omega. + Qed. + + Lemma eval_from_montgomery_mod (v : list Z) : valid v -> eval (from_montgomery_mod v) mod m = (eval v * r'^n) mod m. + Proof. intros; apply from_montgomery_mod_correct; assumption. Qed. + Lemma valid_from_montgomery_mod (v : list Z) + : valid v -> valid (from_montgomery_mod v). + Proof. intros; apply from_montgomery_mod_correct; assumption. Qed. + + Lemma mulmod_correct + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (mulmod a b)) mod m + = (eval (from_montgomery_mod a) * eval (from_montgomery_mod b)) mod m) + /\ (forall a (_ : valid a) b (_ : valid b), valid (mulmod a b)). + Proof. + repeat apply conj; intros; + push_Zmod; rewrite ?eval_from_montgomery_mod; pull_Zmod; repeat apply conj; + try apply mulmod_correct0; cbv [valid] in *; destruct_head'_and; auto; []. + rewrite !Z.mul_assoc. + apply Z.mul_mod_Proper; [ | reflexivity ]. + cbv [Z.equiv_modulo]; etransitivity; [ apply mulmod_correct0 | apply f_equal2; lia ]; auto. + Qed. + + Lemma squaremod_correct + : (forall a (_ : valid a), eval (from_montgomery_mod (squaremod a)) mod m + = (eval (from_montgomery_mod a) * eval (from_montgomery_mod a)) mod m) + /\ (forall a (_ : valid a), valid (squaremod a)). + Proof. + split; intros; cbv [squaremod]; apply mulmod_correct; assumption. + Qed. + + Definition encodemod (v : Z) : list Z + := mulmod (Rows.partition weight n v) R2mod. + + Local Ltac t_valid v := + cbv [valid]; repeat apply conj; + auto; cbv [small eval]; autorewrite with push_eval; auto; + rewrite ?UniformWeight.uweight_eq_alt by omega; + Z.rewrite_mod_small; + rewrite ?(Z.mod_small (_ mod m)) by (subst r; Z.div_mod_to_quot_rem; lia); + rewrite ?(Z.mod_small v) by (subst r; Z.div_mod_to_quot_rem; lia); + try apply Z.mod_pos_bound; subst r; try lia; try reflexivity. + Lemma encodemod_correct + : (forall v, 0 <= v < m -> eval (from_montgomery_mod (encodemod v)) mod m = v mod m) + /\ (forall v, 0 <= v < m -> valid (encodemod v)). + Proof. + split; intros v ?; cbv [encodemod R2mod]; [ rewrite (proj1 mulmod_correct) | apply mulmod_correct ]; + [ | now t_valid v.. ]. + push_Zmod; rewrite !eval_from_montgomery_mod; [ | now t_valid v.. ]. + cbv [eval]; autorewrite with push_eval; auto. + rewrite ?UniformWeight.uweight_eq_alt by omega. + rewrite ?(Z.mod_small v) by (subst r; Z.div_mod_to_quot_rem; lia). + rewrite ?(Z.mod_small (_ mod m)) by (subst r; Z.div_mod_to_quot_rem; lia). + pull_Zmod. + rewrite <- !Z.mul_assoc; autorewrite with pull_Zpow. + generalize r'_correct; push_Zmod; intro Heq; rewrite Heq; clear Heq; pull_Zmod; autorewrite with zsimplify_const. + rewrite (Z.mul_comm r' r); generalize r'_correct; push_Zmod; intro Heq; rewrite Heq; clear Heq; pull_Zmod; autorewrite with zsimplify_const. + Z.rewrite_mod_small. + reflexivity. + Qed. + + Lemma addmod_correct + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (addmod a b)) mod m + = (eval (from_montgomery_mod a) + eval (from_montgomery_mod b)) mod m) + /\ (forall a (_ : valid a) b (_ : valid b), valid (addmod a b)). + Proof. + repeat apply conj; intros; + push_Zmod; rewrite ?eval_from_montgomery_mod; pull_Zmod; repeat apply conj; + cbv [valid addmod] in *; destruct_head'_and; auto; + try rewrite m_enc_correct_montgomery; + try (eapply small_add || eapply add_bound); rewrite <- ?m_enc_correct_montgomery; eauto with omega; []. + push_Zmod; erewrite eval_add by (rewrite <- ?m_enc_correct_montgomery; eauto with omega); pull_Zmod; rewrite <- ?m_enc_correct_montgomery. + break_innermost_match; push_Zmod; pull_Zmod; autorewrite with zsimplify_const; apply f_equal2; nia. + Qed. + + Lemma submod_correct + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (submod a b)) mod m + = (eval (from_montgomery_mod a) - eval (from_montgomery_mod b)) mod m) + /\ (forall a (_ : valid a) b (_ : valid b), valid (submod a b)). + Proof. + repeat apply conj; intros; + push_Zmod; rewrite ?eval_from_montgomery_mod; pull_Zmod; repeat apply conj; + cbv [valid submod] in *; destruct_head'_and; auto; + try rewrite m_enc_correct_montgomery; + try (eapply small_sub || eapply sub_bound); rewrite <- ?m_enc_correct_montgomery; eauto with omega; []. + push_Zmod; erewrite eval_sub by (rewrite <- ?m_enc_correct_montgomery; eauto with omega); pull_Zmod; rewrite <- ?m_enc_correct_montgomery. + break_innermost_match; push_Zmod; pull_Zmod; autorewrite with zsimplify_const; apply f_equal2; nia. + Qed. + + Lemma oppmod_correct + : (forall a (_ : valid a), eval (from_montgomery_mod (oppmod a)) mod m + = (-eval (from_montgomery_mod a)) mod m) + /\ (forall a (_ : valid a), valid (oppmod a)). + Proof. + repeat apply conj; intros; + push_Zmod; rewrite ?eval_from_montgomery_mod; pull_Zmod; repeat apply conj; + cbv [valid oppmod] in *; destruct_head'_and; auto; + try rewrite m_enc_correct_montgomery; + try (eapply small_opp || eapply opp_bound); rewrite <- ?m_enc_correct_montgomery; eauto with omega; []. + push_Zmod; erewrite eval_opp by (rewrite <- ?m_enc_correct_montgomery; eauto with omega); pull_Zmod; rewrite <- ?m_enc_correct_montgomery. + break_innermost_match; push_Zmod; pull_Zmod; autorewrite with zsimplify_const; apply f_equal2; nia. + Qed. + + Lemma nonzeromod_correct + : (forall a (_ : valid a), (nonzeromod a = 0) <-> ((eval (from_montgomery_mod a)) mod m = 0)). + Proof. + intros a Ha; rewrite eval_from_montgomery_mod by assumption. + cbv [nonzeromod valid] in *; destruct_head'_and. + rewrite eval_nonzero; try eassumption; [ | subst r; apply conj; try eassumption; omega.. ]. + split; intro H'; [ rewrite H'; autorewrite with zsimplify_const; reflexivity | ]. + assert (H'' : ((eval a * r'^n) * r^n) mod m = 0) + by (revert H'; push_Zmod; intro H'; rewrite H'; autorewrite with zsimplify_const; reflexivity). + rewrite <- Z.mul_assoc in H''. + autorewrite with pull_Zpow push_Zmod in H''. + rewrite (Z.mul_comm r' r), r'_correct in H''. + autorewrite with zsimplify_const pull_Zmod in H''; [ | lia.. ]. + clear H'. + generalize dependent (eval a); clear. + intros z ???. + assert (z / m = 0) by (Z.div_mod_to_quot_rem; nia). + Z.div_mod_to_quot_rem; nia. + Qed. + + Lemma to_bytesmod_correct + : (forall a (_ : valid a), Positional.eval (UniformWeight.uweight 8) (bytes_n bitwidth 1 n) (to_bytesmod a) + = eval a mod m) + /\ (forall a (_ : valid a), to_bytesmod a = Rows.partition (UniformWeight.uweight 8) (bytes_n bitwidth 1 n) (eval a mod m)). + Proof. + generalize (@length_small bitwidth n); + cbv [valid small to_bytesmod eval]; split; intros; (etransitivity; [ apply eval_to_bytesmod | ]); + fold weight in *; fold (UniformWeight.uweight 8) in *; subst r; + try solve [ intuition eauto with omega ]. + all: repeat first [ rewrite UniformWeight.uweight_eq_alt by omega + | omega + | reflexivity + | progress Z.rewrite_mod_small ]. + Qed. + End modops. +End WordByWordMontgomery. diff --git a/src/Experiments/NewPipeline/CLI.v b/src/Experiments/NewPipeline/CLI.v index 79189637b..3d219049f 100644 --- a/src/Experiments/NewPipeline/CLI.v +++ b/src/Experiments/NewPipeline/CLI.v @@ -204,6 +204,107 @@ Module ForExtraction. end. End UnsaturatedSolinas. + Module WordByWordMontgomery. + Definition PipelineLines + (curve_description : string) + (s : string) + (c : string) + (machine_wordsize : string) + (requests : list string) + : list (string * Pipeline.ErrorT (list string)) + list string + := let prefix := ("fiat_" ++ curve_description ++ "_")%string in + let str_machine_wordsize := machine_wordsize in + let str_c := c in + let str_s := s in + let machine_wordsize := parse_machine_wordsize machine_wordsize in + let show_requests := match requests with nil => "(all)" | _ => String.concat ", " requests end in + match parse_s s, parse_c c with + | None, None + => inr ["Could not parse s (" ++ s ++ ") nor c (" ++ c ++ ")"] + | None, _ + => inr ["Could not parse s (" ++ s ++ ")"] + | _, None + => inr ["Could not parse c (" ++ c ++ ")"] + | Some s, Some c + => let '(res, types_used) + := WordByWordMontgomery.Synthesize s c machine_wordsize prefix requests in + let header := + ((["/* Autogenerated */"; + "/* curve description: " ++ curve_description ++ " */"; + "/* requested operations: " ++ show_requests ++ " */"; + "/* s = " ++ Hex.show_Z false s ++ " (from """ ++ str_s ++ """) */"; + "/* c = " ++ show false c ++ " (from """ ++ str_c ++ """) */"; + "/* machine_wordsize = " ++ show false machine_wordsize ++ " (from """ ++ str_machine_wordsize ++ """) */"; + "/* */"; + "/* NOTE: In addition to the bounds specified above each function, all */"; + "/* functions synthesized for this Montgomery arithmetic require the */"; + "/* input to be strictly less than the prime modulus (s-c), and also */"; + "/* require the input to be in the unique saturated representation. */"; + "/* All functions also ensure that these two properties are true of */"; + "/* return values. */"; + ""]%string) + ++ ToString.C.String.typedef_header prefix types_used + ++ [""])%list in + inl + ([("check_args" ++ NewLine ++ String.concat NewLine header, + WordByWordMontgomery.check_args + s c machine_wordsize + (ErrorT.Success header))%string] + ++ res)%list + end. + + Definition ProcessedLines + (curve_description : string) + (s : string) + (c : string) + (machine_wordsize : string) + (requests : list string) + : list string + list string + := match CollectErrors (PipelineLines curve_description s c machine_wordsize requests) with + | inl ls + => inl + (List.map (fun s => String.concat NewLine s ++ NewLine ++ NewLine) + ls) + | inr nil => inr nil + | inr (l :: ls) + => inr (l ++ (List.flat_map + (fun e => NewLine :: e) + ls))%list + end. + + Definition Pipeline + {A} + (curve_description : string) + (s : string) + (c : string) + (machine_wordsize : string) + (requests : list string) + (success : list string -> A) + (error : list string -> A) + : A + := match ProcessedLines curve_description s c machine_wordsize requests with + | inl s => success s + | inr s => error s + end. + + Definition PipelineMain + {A} + (argv : list string) + (success : list string -> A) + (error : list string -> A) + : A + := match argv with + | _::curve_description::s::c::machine_wordsize::requests + => Pipeline + curve_description s c machine_wordsize requests + success + error + | nil => error ["empty argv"] + | prog::args + => error ["Expected arguments curve_description, s, c, machine_wordsize, [function_to_synthesize*] got " ++ show false (List.length args) ++ " arguments in " ++ prog] + end. + End WordByWordMontgomery. + Module SaturatedSolinas. Definition PipelineLines (curve_description : string) diff --git a/src/Experiments/NewPipeline/CStringification.v b/src/Experiments/NewPipeline/CStringification.v index 5f4f78243..f107a3ddd 100644 --- a/src/Experiments/NewPipeline/CStringification.v +++ b/src/Experiments/NewPipeline/CStringification.v @@ -1092,7 +1092,17 @@ Module Compilers. => fun rout '(e, r) '(offset, roffset) => let rin := option_map integer_promote_type r in match invert_literal offset with - | Some offset => ret (cast_down_if_needed rout (Z_shiftr offset @@ e, rin)) + | Some offset + => (** N.B. We must cast the expression up to a + large enough type to fit 2^offset + (importantly, not just 2^offset-1), + because C considers it to be undefined + behavior to shift >= width of the type. + We should probably figure out how to not + generate these things in the first + place... *) + let '(e', rin') := Zcast_up_if_needed (Some (int.of_zrange_relaxed r[0~>2^offset]%zrange)) (e, rin) in + ret (cast_down_if_needed rout (Z_shiftr offset @@ e', rin')) | None => inr ["Invalid right-shift by a non-literal"]%string end | ident.Z_shiftl @@ -1100,8 +1110,21 @@ Module Compilers. => let rin := option_map integer_promote_type r in match invert_literal offset with | Some offset - => let '(e', rin') := cast_up_if_needed rout (e, rin) in - ret (cast_down_if_needed rout (Z_shiftl offset @@ e', rin')) + => (** N.B. We must cast the expression up to a + large enough type to fit 2^offset + (importantly, not just 2^offset-1), + because C considers it to be undefined + behavior to shift >= width of the type. + We should probably figure out how to not + generate these things in the first + place... *) + let rpre_out := int.of_zrange_relaxed r[0~>2^offset]%zrange in + let rpre_out := match rout with + | Some rout => Some (ToString.C.int.union rout rpre_out) + | None => Some rpre_out + end in + let '(e', rin') := Zcast_up_if_needed rpre_out (e, rin) in + ret (cast_down_if_needed rout (Z_shiftl offset @@ e', rin')) | None => inr ["Invalid left-shift by a non-literal"]%string end | ident.Z_bneg @@ -1442,16 +1465,19 @@ Module Compilers. else inr ["Final bounds check failed on " ++ descr ++ " " ++ show false idc ++ "; expected an unsigned " ++ decimal_string_of_Z s ++ "-bit number (" ++ show false (int.of_zrange_relaxed r[0~>2^s-1]) ++ "), but found a " ++ show false ty ++ "."]%string end. + Let round_up_to_split_type (lgs : Z) (t : option int.type) : option int.type + := option_map (int.union (int.of_zrange_relaxed r[0~>2^lgs-1])) t. + Let recognize_3arg_2ref_ident (do_bounds_check : bool) (t:=(base.type.Z -> base.type.Z -> base.type.Z -> base.type.Z * base.type.Z)%etype) (idc : ident.ident t) (rout : option int.type * option int.type) (args : type.for_each_lhs_of_arrow (fun t => @Compilers.expr.expr base.type ident.ident var_data t * (arith_expr type.Z * option int.type))%type t) - : ErrT (arith_expr (type.Zptr * type.Zptr) -> expr) + : ErrT ((option int.type * option int.type) * (arith_expr (type.Zptr * type.Zptr) -> expr)) := let _ := @PHOAS.expr.partially_show_expr in let '((s, _), ((e1v, (e1, r1)), ((e2v, (e2, r2)), tt))) := args in - match (s <- invert_Literal s; maybe_log2 s)%option, idc return ErrT (arith_expr (type.Zptr * type.Zptr) -> expr) + match (s <- invert_Literal s; maybe_log2 s)%option, idc return ErrT ((option int.type * option int.type) * (arith_expr (type.Zptr * type.Zptr) -> expr)) with | Some s, ident.Z_mul_split => (_ ,, _ ,, _ ,, _ @@ -1459,7 +1485,8 @@ Module Compilers. bounds_check do_bounds_check "second argument to" idc s e2v r2, bounds_check do_bounds_check "first return value of" idc s e2v (fst rout), bounds_check do_bounds_check "second return value of" idc s e2v (snd rout); - inl (fun retptr => [Call (Z_mul_split s @@ (retptr, (e1, e2)))%Cexpr])) + inl ((round_up_to_split_type s (fst rout), round_up_to_split_type s (snd rout)), + fun retptr => [Call (Z_mul_split s @@ (retptr, (e1, e2)))%Cexpr])) | Some s, ident.Z_add_get_carry as idc | Some s, ident.Z_sub_get_borrow as idc => let idc' : ident _ _ := invert_Some match idc with @@ -1472,7 +1499,8 @@ Module Compilers. bounds_check do_bounds_check "second argument to" idc s e2v r2, bounds_check do_bounds_check "first return value of" idc s e2v (fst rout), bounds_check do_bounds_check "second return value of" idc 1 (* boolean carry/borrow *) e2v (snd rout); - inl (fun retptr => [Call (idc' @@ (retptr, (literal 0 @@ TT, e1, e2)))%Cexpr])) + inl ((round_up_to_split_type s (fst rout), snd rout), + fun retptr => [Call (idc' @@ (retptr, (literal 0 @@ TT, e1, e2)))%Cexpr])) | Some _, _ => inr ["Unrecognized identifier when attempting to construct an assignment with 2 arguments: " ++ show true idc]%string | None, _ => inr ["Expression is not a literal power of two of type ℤ: " ++ show true s ++ " (when trying to parse the first argument of " ++ show true idc ++ ")"]%string end. @@ -1483,10 +1511,10 @@ Module Compilers. (idc : ident.ident t) (rout : option int.type * option int.type) (args : type.for_each_lhs_of_arrow (fun t => @Compilers.expr.expr base.type ident.ident var_data t * (arith_expr type.Z * option int.type))%type t) - : ErrT (arith_expr (type.Zptr * type.Zptr) -> expr) + : ErrT ((option int.type * option int.type) * (arith_expr (type.Zptr * type.Zptr) -> expr)) := let _ := @PHOAS.expr.partially_show_expr in let '((s, _), ((e1v, (e1, r1)), ((e2v, (e2, r2)), ((e3v, (e3, r3)), tt)))) := args in - match (s <- invert_Literal s; maybe_log2 s)%option, idc return ErrT (arith_expr (type.Zptr * type.Zptr) -> expr) + match (s <- invert_Literal s; maybe_log2 s)%option, idc return ErrT ((option int.type * option int.type) * (arith_expr (type.Zptr * type.Zptr) -> expr)) with | Some s, ident.Z_add_with_get_carry as idc | Some s, ident.Z_sub_with_get_borrow as idc @@ -1501,7 +1529,8 @@ Module Compilers. bounds_check do_bounds_check "third argument to" idc s e2v r2, bounds_check do_bounds_check "first return value of" idc s e2v (fst rout), bounds_check do_bounds_check "second (carry) return value of" idc 1 (* boolean carry/borrow *) e2v (snd rout)); - inl (fun retptr => [Call (idc' @@ (retptr, (e1, e2, e3)))%Cexpr])) + inl ((round_up_to_split_type s (fst rout), snd rout), + fun retptr => [Call (idc' @@ (retptr, (e1, e2, e3)))%Cexpr])) | Some _, _ => inr ["Unrecognized identifier when attempting to construct an assignment with 2 arguments: " ++ show true idc]%string | None, _ => inr ["Expression is not a literal power of two of type ℤ: " ++ show true s ++ " (when trying to parse the first argument of " ++ show true idc ++ ")"]%string end. @@ -1512,7 +1541,7 @@ Module Compilers. (idc : ident.ident t) (rout : option int.type * option int.type) (args : type.for_each_lhs_of_arrow (fun t => @Compilers.expr.expr base.type ident.ident var_data t * (arith_expr type.Z * option int.type))%type t), - ErrT (arith_expr (type.Zptr * type.Zptr) -> expr) + ErrT ((option int.type * option int.type) * (arith_expr (type.Zptr * type.Zptr) -> expr)) := match t with | (type.base base.type.Z -> type.base base.type.Z -> type.base base.type.Z -> type.base (base.type.Z * base.type.Z))%etype => recognize_3arg_2ref_ident @@ -1585,7 +1614,8 @@ Module Compilers. match invert_AppIdent_curried e with | Some (existT t (idc, args)) => args <- arith_expr_of_PHOAS_args args; - idce <- recognize_2ref_ident do_bounds_check idc (rout1, rout2) args; + idce <- recognize_2ref_ident do_bounds_check idc (rout1, rout2) args; + let '((rout1, rout2), idce) := idce in v1,, v2 <- (declare_name (show false idc) count make_name rout1, declare_name (show false idc) (Pos.succ count) make_name rout2); let '(decls1, n1, retv1) := v1 in @@ -1638,7 +1668,7 @@ Module Compilers. (make_name : positive -> option string) (v : var_data d) : ErrT expr - := Eval cbv beta iota delta [bind2_err bind3_err bind4_err bind5_err recognize_1ref_ident recognize_3arg_2ref_ident recognize_4arg_2ref_ident recognize_2ref_ident make_assign_arg_1ref_opt make_assign_arg_2ref make_assign_arg_ref make_uniform_assign_expr_of_PHOAS make_uniform_assign_expr_of_PHOAS] in + := Eval cbv beta iota delta [bind2_err bind3_err bind4_err bind5_err recognize_1ref_ident recognize_3arg_2ref_ident recognize_4arg_2ref_ident recognize_2ref_ident make_assign_arg_1ref_opt make_assign_arg_2ref make_assign_arg_ref make_uniform_assign_expr_of_PHOAS make_uniform_assign_expr_of_PHOAS round_up_to_split_type] in match type.try_transport base.try_make_transport_cps _ _ s' e1 with | Some e1 => make_uniform_assign_expr_of_PHOAS do_bounds_check e1 e2 count make_name v | None => inr [report_type_mismatch s' s] diff --git a/src/Experiments/NewPipeline/CompilersTestCases.v b/src/Experiments/NewPipeline/CompilersTestCases.v index 0fa697fbe..3d8204fbf 100644 --- a/src/Experiments/NewPipeline/CompilersTestCases.v +++ b/src/Experiments/NewPipeline/CompilersTestCases.v @@ -43,21 +43,21 @@ Module testrewrite. Import expr. Import ident. - Eval compute in RewriteRules.Rewrite (fun var => + Eval compute in RewriteRules.RewriteNBE (fun var => (#ident.fst @ (expr_let x := ##10 in ($x, $x)))%expr). Notation "x + y" := (@expr.Ident base.type ident _ _ ident.Z_add @ x @ y)%expr : expr_scope. - Eval compute in RewriteRules.Rewrite (fun var => + Eval compute in RewriteRules.RewriteNBE (fun var => ((\ x , expr_let y := ##5 in #ident.fst @ $x + (#ident.fst @ $x + ($y + $y))) @ (##1, ##1))%expr). - Eval compute in RewriteRules.Rewrite (fun var => + Eval compute in RewriteRules.RewriteNBE (fun var => ((\ x , expr_let y := ##5 in $y + ($y + (#ident.fst @ $x + #ident.snd @ $x))) @ (##1, ##7))%expr). - Eval cbv in partial.eval_with_bound (RewriteRules.Rewrite (fun var => + Eval cbv in partial.eval_with_bound (RewriteRules.RewriteNBE (fun var => (\z , ((\ x , expr_let y := ##5 in $y + ($z + (#ident.fst @ $x + #ident.snd @ $x))) @ (##1, ##7)))%expr) _) (Some r[0~>100]%zrange, tt). diff --git a/src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.v b/src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.v new file mode 100644 index 000000000..5ac65a524 --- /dev/null +++ b/src/Experiments/NewPipeline/ExtractionHaskell/word_by_word_montgomery.v @@ -0,0 +1,4 @@ +Require Import Crypto.Experiments.NewPipeline.StandaloneHaskellMain. + +(*Redirect "/tmp/word_by_word_montgomery.hs" *)Recursive Extraction WordByWordMontgomery.main. +(* cat /tmp/solinas.hs.out | sed -f haskell.sed > ../../solinas.hs *) diff --git a/src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.v b/src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.v new file mode 100644 index 000000000..083e53a30 --- /dev/null +++ b/src/Experiments/NewPipeline/ExtractionOCaml/word_by_word_montgomery.v @@ -0,0 +1,3 @@ +Require Import Crypto.Experiments.NewPipeline.StandaloneOCamlMain. + +(*Redirect "/tmp/word_by_word_montgomery.ml"*) Recursive Extraction WordByWordMontgomery.main. diff --git a/src/Experiments/NewPipeline/Language.v b/src/Experiments/NewPipeline/Language.v index 971ae81ef..b3a7ea235 100644 --- a/src/Experiments/NewPipeline/Language.v +++ b/src/Experiments/NewPipeline/Language.v @@ -524,10 +524,17 @@ Module Compilers. | match ?x with nil => ?N | cons a b => @?C a b end => let T := type of term in reify_rec (@list_case _ (fun _ => T) N C x) - | let x := ?a in @?b x + | let x := ?a in ?b => let A := type of a in - let B := lazymatch type of b with forall x, @?B x => B end in - reify_rec (b a) (*(@Let_In A B a b)*) + let T := type of term in + let rec_val := match constr:(Set) with + | _ => let v := constr:((fun x : A => b) a) in + let __ := type of v in (* ensure that the abstraction is well-typed, i.e., that we're not relying on the value of the let to well-type the body *) + v + | _ => constr:(match a return T with x => b end) (* if we do rely on the body of [x] to well-type [b], then just inline it *) + end in + (*let B := lazymatch type of b with forall x, @?B x => B end in*) + reify_rec rec_val (*(@Let_In A B a b)*) | @Let_In ?A ?B ?a ?b => let ra := reify_rec a in let rb := reify_rec b in @@ -1047,36 +1054,60 @@ Module Compilers. => let rA := base.reify A in let rB := base.reify B in then_tac (@ident.pair rA rB) - | @Datatypes.bool_rect (fun _ => ?T) ?Ptrue ?Pfalse - => reify_rec (@Thunked.bool_rect T (fun _ : Datatypes.unit => Ptrue) (fun _ : Datatypes.unit => Pfalse)) + | @Datatypes.bool_rect ?T0 ?Ptrue ?Pfalse + => lazymatch (eval cbv beta in T0) with + | fun _ => ?T => reify_rec (@Thunked.bool_rect T (fun _ : Datatypes.unit => Ptrue) (fun _ : Datatypes.unit => Pfalse)) + | T0 => else_tac () + | ?T' => reify_rec (@Datatypes.bool_rect T' Ptrue Pfalse) + end | @Thunked.bool_rect ?T => let rT := base.reify T in then_tac (@ident.bool_rect rT) - | @Datatypes.prod_rect ?A ?B (fun _ => ?T) - => let rA := base.reify A in - let rB := base.reify B in - let rT := base.reify T in - then_tac (@ident.prod_rect rA rB rT) - | @Datatypes.nat_rect (fun _ => ?T) ?P0 - => lazymatch T with - | _ -> _ => else_tac () - | _ => reify_rec (@Thunked.nat_rect T (fun _ : Datatypes.unit => P0)) + | @Datatypes.prod_rect ?A ?B ?T0 + => lazymatch (eval cbv beta in T0) with + | fun _ => ?T + => let rA := base.reify A in + let rB := base.reify B in + let rT := base.reify T in + then_tac (@ident.prod_rect rA rB rT) + | T0 => else_tac () + | ?T' => reify_rec (@Datatypes.prod_rect A B T') + end + | @Datatypes.nat_rect ?T0 ?P0 + => lazymatch (eval cbv beta in T0) with + | fun _ => _ -> _ => else_tac () + | fun _ => ?T => reify_rec (@Thunked.nat_rect T (fun _ : Datatypes.unit => P0)) + | T0 => else_tac () + | ?T' => reify_rec (@Datatypes.nat_rect T' P0) end - | @Datatypes.nat_rect (fun _ => ?P -> ?Q) - => let rP := base.reify P in - let rQ := base.reify Q in - then_tac (@ident.nat_rect_arrow rP rQ) + | @Datatypes.nat_rect ?T0 + => lazymatch (eval cbv beta in T0) with + | (fun _ => ?P -> ?Q) + => let rP := base.reify P in + let rQ := base.reify Q in + then_tac (@ident.nat_rect_arrow rP rQ) + | T0 => else_tac () + | ?T' => reify_rec (@Datatypes.nat_rect T') + end | @Thunked.nat_rect ?T => let rT := base.reify T in then_tac (@ident.nat_rect rT) - | @Datatypes.list_rect ?A (fun _ => ?T) ?Pnil - => reify_rec (@Thunked.list_rect A T (fun _ : Datatypes.unit => Pnil)) + | @Datatypes.list_rect ?A ?T0 ?Pnil + => lazymatch (eval cbv beta in T0) with + | fun _ => ?T => reify_rec (@Thunked.list_rect A T (fun _ : Datatypes.unit => Pnil)) + | T0 => else_tac () + | ?T' => reify_rec (@Datatypes.list_rect A T' Pnil) + end | @Thunked.list_rect ?A ?T => let rA := base.reify A in let rT := base.reify T in then_tac (@ident.list_rect rA rT) - | @ListUtil.list_case ?A (fun _ => ?T) ?Pnil - => reify_rec (@Thunked.list_case A T (fun _ : Datatypes.unit => Pnil)) + | @ListUtil.list_case ?A ?T0 ?Pnil + => lazymatch (eval cbv beta in T0) with + | fun _ => ?T => reify_rec (@Thunked.list_case A T (fun _ : Datatypes.unit => Pnil)) + | T0 => else_tac () + | ?T' => reify_rec (@ListUtil.list_case A T' Pnil) + end | @Thunked.list_case ?A ?T => let rA := base.reify A in let rT := base.reify T in diff --git a/src/Experiments/NewPipeline/Rewriter.v b/src/Experiments/NewPipeline/Rewriter.v index 599a7d34e..f9f6e22ac 100644 --- a/src/Experiments/NewPipeline/Rewriter.v +++ b/src/Experiments/NewPipeline/Rewriter.v @@ -1153,7 +1153,7 @@ In the RHS, the follow notation applies: If stuck, email Jason. *) - Definition rewrite_rules : rewrite_rulesT + Definition nbe_rewrite_rules : rewrite_rulesT := Eval cbn [Make.interp_rewrite_rules List.app] in Make.interp_rewrite_rules ++ [ @@ -1275,131 +1275,219 @@ In the RHS, the follow notation applies: (fun x => x <-- x; f x) (List.map UnderLets.Base ls)); reify_list retv)) - ; make_rewrite (#?ℤ + ??{ℤ}) (fun z v => v when Z.eqb z 0) - ; make_rewrite (??{ℤ} + #?ℤ ) (fun v z => v when Z.eqb z 0) - ; make_rewrite (#?ℤ + (-??{ℤ})) (fun z v => ##z - v when Z.gtb z 0) - ; make_rewrite ((-??{ℤ}) + #?ℤ ) (fun v z => ##z - v when Z.gtb z 0) - ; make_rewrite (#?ℤ + (-??{ℤ})) (fun z v => -(##((-z)%Z) + v) when Z.ltb z 0) - ; make_rewrite ((-??{ℤ}) + #?ℤ ) (fun v z => -(v + ##((-z)%Z)) when Z.ltb z 0) - ; make_rewrite ((-??{ℤ}) + (-??{ℤ})) (fun x y => -(x + y)) - ; make_rewrite ((-??{ℤ}) + ??{ℤ} ) (fun x y => y - x) - ; make_rewrite ( ??{ℤ} + (-??{ℤ})) (fun x y => x - y) - - ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => v when Z.eqb z 0) - ; make_rewrite (#?ℤ - ??{ℤ} ) (fun z v => -v when Z.eqb z 0) - ; make_rewrite (??{ℤ} - #?ℤ ) (fun v z => v when Z.eqb z 0) - ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => ##z + v when Z.gtb z 0) - ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => v - ##((-z)%Z) when Z.ltb z 0) - ; make_rewrite (#?ℤ - ??{ℤ} ) (fun z v => -(##((-z)%Z) + v) when Z.ltb z 0) - ; make_rewrite ((-??{ℤ}) - #?ℤ ) (fun v z => -(v + ##((-z)%Z)) when Z.gtb z 0) - ; make_rewrite ((-??{ℤ}) - #?ℤ ) (fun v z => ##((-z)%Z) - v when Z.ltb z 0) - ; make_rewrite ( ??{ℤ} - #?ℤ ) (fun v z => v + ##((-z)%Z) when Z.ltb z 0) - ; make_rewrite ((-??{ℤ}) - (-??{ℤ})) (fun x y => y - x) - ; make_rewrite ((-??{ℤ}) - ??{ℤ} ) (fun x y => -(x + y)) - ; make_rewrite ( ??{ℤ} - (-??{ℤ})) (fun x y => x + y) - - ; make_rewrite (#?ℤ * ??{ℤ}) (fun z v => ##0 when Z.eqb z 0) - ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => ##0 when Z.eqb z 0) - ; make_rewrite (#?ℤ * ??{ℤ}) (fun z v => v when Z.eqb z 1) - ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => v when Z.eqb z 1) - ; make_rewrite (#?ℤ * (-??{ℤ})) (fun z v => v when Z.eqb z (-1)) - ; make_rewrite ((-??{ℤ}) * #?ℤ ) (fun v z => v when Z.eqb z (-1)) - ; make_rewrite (#?ℤ * ??{ℤ} ) (fun z v => -v when Z.eqb z (-1)) - ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => -v when Z.eqb z (-1)) - ; make_rewrite (#?ℤ * ??{ℤ} ) (fun z v => -(##((-z)%Z) * v) when Z.ltb z 0) - ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => -(v * ##((-z)%Z)) when Z.ltb z 0) - ; make_rewrite ((-??{ℤ}) * (-??{ℤ})) (fun x y => x * y) - ; make_rewrite ((-??{ℤ}) * ??{ℤ} ) (fun x y => -(x * y)) - ; make_rewrite ( ??{ℤ} * (-??{ℤ})) (fun x y => -(x * y)) - - ; make_rewrite (??{ℤ} * #?ℤ) (fun x y => x << ##(Z.log2 y) when (y =? (2^Z.log2 y)) && (negb (y =? 2))) - ; make_rewrite (#?ℤ * ??{ℤ}) (fun y x => x << ##(Z.log2 y) when (y =? (2^Z.log2 y)) && (negb (y =? 2))) - ; make_rewrite (??{ℤ} / #?ℤ) (fun x y => x >> ##(Z.log2 y) when Z.eqb y (2^Z.log2 y)) - ; make_rewrite (??{ℤ} mod #?ℤ) (fun x y => x &' ##(y-1)%Z when Z.eqb y (2^Z.log2 y)) - ; make_rewrite (-(-??{ℤ})) (fun v => v) - - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (##0, ##0)%Z when Z.eqb xx 0) - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (##0, ##0)%Z when Z.eqb xx 0) - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (y, ##0)%Z when Z.eqb xx 1) - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (y, ##0)%Z when Z.eqb xx 1) - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (-y, ##0%Z) when Z.eqb xx (-1)) - ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (-y, ##0%Z) when Z.eqb xx (-1)) - - ; make_rewrite (#pident.Z_add_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ}) (fun s xx y => (y, ##0) when xx =? 0) - ; make_rewrite (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ) (fun s y xx => (y, ##0) when xx =? 0) - - ; make_rewrite (#pident.Z_add_with_carry @ #?ℤ @ ??{ℤ} @ ??{ℤ}) (fun cc x y => x + y when cc =? 0) - - ; make_rewrite - (#pident.Z_add_with_get_carry @ #?ℤ @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s cc xx y => (y, ##0) when (cc =? 0) && (xx =? 0)) - ; make_rewrite - (#pident.Z_add_with_get_carry @ #?ℤ @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s cc y xx => (y, ##0) when (cc =? 0) && (xx =? 0)) - ; make_rewrite (* carry = 0: ADC x y -> ADD x y *) - (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ} @ ??{ℤ}) - (fun s cc x y => #ident.Z_add_get_carry @ s @ x @ y when cc =? 0) - ; make_rewrite (* ADC 0 0 -> (ADX 0 0, 0) *) - (#pident.Z_add_with_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ @ #?ℤ) - (fun s c xx yy => #ident.Z_add_with_carry @ s @ ##xx @ ##yy when (xx =? 0) && (yy =? 0)) - - ; make_rewrite - (#pident.Z_add_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ}) - (fun s y x => ret (UnderLets.UnderLet - (#ident.Z_sub_get_borrow @ s @ x @ y) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) - ; make_rewrite - (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ (-??{ℤ})) - (fun s x y => ret (UnderLets.UnderLet - (#ident.Z_sub_get_borrow @ s @ x @ y) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) - ; make_rewrite - (#pident.Z_add_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ}) - (fun s yy x => ret (UnderLets.UnderLet - (#ident.Z_sub_get_borrow @ s @ x @ ##(-yy)%Z) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) - when yy <=? 0) - ; make_rewrite - (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ) - (fun s x yy => ret (UnderLets.UnderLet - (#ident.Z_sub_get_borrow @ s @ x @ ##(-yy)%Z) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) - when yy <=? 0) - - - ; make_rewrite - (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ (-??{ℤ}) @ ??{ℤ}) - (fun s c y x => ret (UnderLets.UnderLet - (#ident.Z_sub_with_get_borrow @ s @ c @ x @ y) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) - ; make_rewrite - (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ} @ (-??{ℤ})) - (fun s c x y => ret (UnderLets.UnderLet - (#ident.Z_sub_with_get_borrow @ s @ c @ x @ y) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) - ; make_rewrite - (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ #?ℤ @ ??{ℤ}) - (fun s c yy x => ret (UnderLets.UnderLet - (#ident.Z_sub_with_get_borrow @ s @ c @ x @ ##(-yy)%Z) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) - when yy <=? 0) - ; make_rewrite - (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ} @ #?ℤ) - (fun s c x yy => ret (UnderLets.UnderLet - (#ident.Z_sub_with_get_borrow @ s @ c @ x @ ##(-yy)%Z) - (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) - when yy <=? 0) - - - ; make_rewrite_step (* _step, so that if one of the arguments is concrete, we automatically get the rewrite rule for [Z_cast] applying to it *) - (#pident.Z_cast2 @ (??{ℤ}, ??{ℤ})) (fun r x y => (#(ident.Z_cast (fst r)) @ $x, #(ident.Z_cast (snd r)) @ $y)) - - ; make_rewrite (-??{ℤ}) (fun e => ret (UnderLets.UnderLet e (fun v => UnderLets.Base (-$v))) when negb (SubstVarLike.is_var_fst_snd_pair_opp e)) (* inline negation when the rewriter wouldn't already inline it *) ]%list%pattern%cps%option%under_lets%Z%bool. - Definition dtree' - := Eval compute in @compile_rewrites ident var pattern.ident pattern.ident.arg_types pattern.ident.ident_beq 100 rewrite_rules. - Definition dtree : decision_tree - := Eval compute in invert_Some dtree'. - Definition default_fuel := Eval compute in List.length rewrite_rules. + Definition arith_rewrite_rules : rewrite_rulesT + := [make_rewrite (#pident.fst @ (??, ??)) (fun _ x _ y => x) + ; make_rewrite (#pident.snd @ (??, ??)) (fun _ x _ y => y) + ; make_rewrite (#?ℤ + ??{ℤ}) (fun z v => v when Z.eqb z 0) + ; make_rewrite (??{ℤ} + #?ℤ ) (fun v z => v when Z.eqb z 0) + ; make_rewrite (#?ℤ + (-??{ℤ})) (fun z v => ##z - v when Z.gtb z 0) + ; make_rewrite ((-??{ℤ}) + #?ℤ ) (fun v z => ##z - v when Z.gtb z 0) + ; make_rewrite (#?ℤ + (-??{ℤ})) (fun z v => -(##((-z)%Z) + v) when Z.ltb z 0) + ; make_rewrite ((-??{ℤ}) + #?ℤ ) (fun v z => -(v + ##((-z)%Z)) when Z.ltb z 0) + ; make_rewrite ((-??{ℤ}) + (-??{ℤ})) (fun x y => -(x + y)) + ; make_rewrite ((-??{ℤ}) + ??{ℤ} ) (fun x y => y - x) + ; make_rewrite ( ??{ℤ} + (-??{ℤ})) (fun x y => x - y) + + ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => v when Z.eqb z 0) + ; make_rewrite (#?ℤ - ??{ℤ} ) (fun z v => -v when Z.eqb z 0) + ; make_rewrite (??{ℤ} - #?ℤ ) (fun v z => v when Z.eqb z 0) + ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => ##z + v when Z.gtb z 0) + ; make_rewrite (#?ℤ - (-??{ℤ})) (fun z v => v - ##((-z)%Z) when Z.ltb z 0) + ; make_rewrite (#?ℤ - ??{ℤ} ) (fun z v => -(##((-z)%Z) + v) when Z.ltb z 0) + ; make_rewrite ((-??{ℤ}) - #?ℤ ) (fun v z => -(v + ##((-z)%Z)) when Z.gtb z 0) + ; make_rewrite ((-??{ℤ}) - #?ℤ ) (fun v z => ##((-z)%Z) - v when Z.ltb z 0) + ; make_rewrite ( ??{ℤ} - #?ℤ ) (fun v z => v + ##((-z)%Z) when Z.ltb z 0) + ; make_rewrite ((-??{ℤ}) - (-??{ℤ})) (fun x y => y - x) + ; make_rewrite ((-??{ℤ}) - ??{ℤ} ) (fun x y => -(x + y)) + ; make_rewrite ( ??{ℤ} - (-??{ℤ})) (fun x y => x + y) + + ; make_rewrite (#?ℤ * ??{ℤ}) (fun z v => ##0 when Z.eqb z 0) + ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => ##0 when Z.eqb z 0) + ; make_rewrite (#?ℤ * ??{ℤ}) (fun z v => v when Z.eqb z 1) + ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => v when Z.eqb z 1) + ; make_rewrite (#?ℤ * (-??{ℤ})) (fun z v => v when Z.eqb z (-1)) + ; make_rewrite ((-??{ℤ}) * #?ℤ ) (fun v z => v when Z.eqb z (-1)) + ; make_rewrite (#?ℤ * ??{ℤ} ) (fun z v => -v when Z.eqb z (-1)) + ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => -v when Z.eqb z (-1)) + ; make_rewrite (#?ℤ * ??{ℤ} ) (fun z v => -(##((-z)%Z) * v) when Z.ltb z 0) + ; make_rewrite (??{ℤ} * #?ℤ ) (fun v z => -(v * ##((-z)%Z)) when Z.ltb z 0) + ; make_rewrite ((-??{ℤ}) * (-??{ℤ})) (fun x y => x * y) + ; make_rewrite ((-??{ℤ}) * ??{ℤ} ) (fun x y => -(x * y)) + ; make_rewrite ( ??{ℤ} * (-??{ℤ})) (fun x y => -(x * y)) + + ; make_rewrite (??{ℤ} &' #?ℤ) (fun x mask => ##(0)%Z when mask =? 0) + ; make_rewrite (#?ℤ &' ??{ℤ}) (fun mask x => ##(0)%Z when mask =? 0) + + ; make_rewrite (??{ℤ} * #?ℤ) (fun x y => x << ##(Z.log2 y) when (y =? (2^Z.log2 y)) && (negb (y =? 2))) + ; make_rewrite (#?ℤ * ??{ℤ}) (fun y x => x << ##(Z.log2 y) when (y =? (2^Z.log2 y)) && (negb (y =? 2))) + ; make_rewrite (??{ℤ} / #?ℤ) (fun x y => x when (y =? 1)) + ; make_rewrite (??{ℤ} mod #?ℤ) (fun x y => ##(0)%Z when (y =? 1)) + ; make_rewrite (??{ℤ} / #?ℤ) (fun x y => x >> ##(Z.log2 y) when (y =? (2^Z.log2 y))) + ; make_rewrite (??{ℤ} mod #?ℤ) (fun x y => x &' ##(y-1)%Z when (y =? (2^Z.log2 y))) + ; make_rewrite (-(-??{ℤ})) (fun v => v) + + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (##0, ##0)%Z when Z.eqb xx 0) + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (##0, ##0)%Z when Z.eqb xx 0) + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (y, ##0)%Z when Z.eqb xx 1) + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (y, ##0)%Z when Z.eqb xx 1) + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s xx y => (-y, ##0%Z) when Z.eqb xx (-1)) + ; make_rewrite (#pident.Z_mul_split @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s y xx => (-y, ##0%Z) when Z.eqb xx (-1)) + + ; make_rewrite + (#pident.Z_add_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ}) + (fun s y x => ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) + ; make_rewrite + (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ (-??{ℤ})) + (fun s x y => ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) + ; make_rewrite + (#pident.Z_add_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ}) + (fun s yy x => ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when yy ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when yy ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ c @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ} @ (-??{ℤ})) + (fun s c x y => ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ c @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc))))) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ (-??{ℤ}) @ ??{ℤ}) + (fun s cc y x => ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when cc =? 0) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ (-??{ℤ}) @ ??{ℤ}) + (fun s cc y x => ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ ##(-cc)%Z @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when cc ret (UnderLets.UnderLet + (#ident.Z_sub_get_borrow @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when cc =? 0) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ} @ (-??{ℤ})) + (fun s cc x y => ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ ##(-cc)%Z @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when cc ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ c @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when yy <=? 0) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ (-??{ℤ}) @ ??{ℤ} @ #?ℤ) + (fun s c x yy => ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ c @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when yy <=? 0) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ #?ℤ @ ??{ℤ}) + (fun s cc yy x => ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ ##(-cc)%Z @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when (yy <=? 0) && (cc <=? 0) && ((yy + cc) ret (UnderLets.UnderLet + (#ident.Z_sub_with_get_borrow @ s @ ##(-cc)%Z @ x @ ##(-yy)%Z) + (fun vc => UnderLets.Base (#ident.fst @ $vc, -(#ident.snd @ $vc)))) + when (yy <=? 0) && (cc <=? 0) && ((yy + cc) (y, ##0) when xx =? 0) + ; make_rewrite (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ) (fun s y xx => (y, ##0) when xx =? 0) + + ; make_rewrite (#pident.Z_add_with_carry @ #?ℤ @ ??{ℤ} @ ??{ℤ}) (fun cc x y => x + y when cc =? 0) + (*; make_rewrite_step (#pident.Z_add_with_carry @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) (fun x y z => $x + $y + $z)*) + + ; make_rewrite + (#pident.Z_add_with_get_carry @ #?ℤ @ #?ℤ @ #?ℤ @ ??{ℤ}) (fun s cc xx y => (y, ##0) when (cc =? 0) && (xx =? 0)) + ; make_rewrite + (#pident.Z_add_with_get_carry @ #?ℤ @ #?ℤ @ ??{ℤ} @ #?ℤ) (fun s cc y xx => (y, ##0) when (cc =? 0) && (xx =? 0)) + (*; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ @ #?ℤ) (fun s c xx yy => (c, ##0) when (xx =? 0) && (yy =? 0))*) + ; make_rewrite (* carry = 0: ADC x y -> ADD x y *) + (#pident.Z_add_with_get_carry @ ??{ℤ} @ #?ℤ @ ??{ℤ} @ ??{ℤ}) + (fun s cc x y => ret (UnderLets.UnderLet + (#ident.Z_add_get_carry @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, #ident.snd @ $vc))) + when cc =? 0) + ; make_rewrite (* ADC 0 0 -> (ADX 0 0, 0) *) (* except we don't do ADX, because C stringification doesn't handle it *) + (#pident.Z_add_with_get_carry @ ??{ℤ} @ ??{ℤ} @ #?ℤ @ #?ℤ) + (fun s c xx yy => ret (UnderLets.UnderLet + (#ident.Z_add_with_get_carry @ s @ c @ ##xx @ ##yy) + (fun vc => UnderLets.Base (#ident.fst @ $vc, ##0))) + when (xx =? 0) && (yy =? 0)) + + + (* let-bind any adc/sbb/mulx *) + ; make_rewrite + (#pident.Z_add_with_get_carry @ ??{ℤ} @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun s c x y => ret (UnderLets.UnderLet (#ident.Z_add_with_get_carry @ s @ c @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, #ident.snd @ $vc)))) + ; make_rewrite + (#pident.Z_add_with_carry @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun c x y => ret (UnderLets.UnderLet (#ident.Z_add_with_carry @ c @ x @ y) + (fun vc => UnderLets.Base ($vc)))) + ; make_rewrite + (#pident.Z_add_get_carry @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun s x y => ret (UnderLets.UnderLet (#ident.Z_add_get_carry @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, #ident.snd @ $vc)))) + ; make_rewrite + (#pident.Z_sub_with_get_borrow @ ??{ℤ} @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun s c x y => ret (UnderLets.UnderLet (#ident.Z_sub_with_get_borrow @ s @ c @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, #ident.snd @ $vc)))) + ; make_rewrite + (#pident.Z_sub_get_borrow @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun s x y => ret (UnderLets.UnderLet (#ident.Z_sub_get_borrow @ s @ x @ y) + (fun vc => UnderLets.Base (#ident.fst @ $vc, #ident.snd @ $vc)))) + ; make_rewrite + (#pident.Z_mul_split @ ??{ℤ} @ ??{ℤ} @ ??{ℤ}) + (fun s x y => ret (UnderLets.UnderLet (#ident.Z_mul_split @ s @ x @ y) + (fun v => UnderLets.Base (#ident.fst @ $v, #ident.snd @ $v)))) + + + ; make_rewrite_step (* _step, so that if one of the arguments is concrete, we automatically get the rewrite rule for [Z_cast] applying to it *) + (#pident.Z_cast2 @ (??{ℤ}, ??{ℤ})) (fun r x y => (#(ident.Z_cast (fst r)) @ $x, #(ident.Z_cast (snd r)) @ $y)) + + ; make_rewrite (-??{ℤ}) (fun e => ret (UnderLets.UnderLet e (fun v => UnderLets.Base (-$v))) when negb (SubstVarLike.is_var_fst_snd_pair_opp e)) (* inline negation when the rewriter wouldn't already inline it *) + ]%list%pattern%cps%option%under_lets%Z%bool. + + Definition nbe_dtree' + := Eval compute in @compile_rewrites ident var pattern.ident pattern.ident.arg_types pattern.ident.ident_beq 100 nbe_rewrite_rules. + Definition arith_dtree' + := Eval compute in @compile_rewrites ident var pattern.ident pattern.ident.arg_types pattern.ident.ident_beq 100 arith_rewrite_rules. + Definition nbe_dtree : decision_tree + := Eval compute in invert_Some nbe_dtree'. + Definition arith_dtree : decision_tree + := Eval compute in invert_Some arith_dtree'. + Definition nbe_default_fuel := Eval compute in List.length nbe_rewrite_rules. + Definition arith_default_fuel := Eval compute in List.length arith_rewrite_rules. Import PrimitiveHList. (* N.B. The [combine_hlist] call MUST eta-expand @@ -1414,13 +1502,21 @@ In the RHS, the follow notation applies: trying to reduce things.) We accomplish this by making [hlist] based on a primitive [prod] type with judgmental η, so that matching on its structure never blocks reduction. *) - Definition split_rewrite_rules := Eval cbv [split_list projT1 projT2 rewrite_rules] in split_list rewrite_rules. - Definition pr1_rewrite_rules := Eval hnf in projT1 split_rewrite_rules. - Definition pr2_rewrite_rules := Eval hnf in projT2 split_rewrite_rules. - Definition all_rewrite_rules := combine_hlist (P:=rewrite_ruleTP) pr1_rewrite_rules pr2_rewrite_rules. + Definition nbe_split_rewrite_rules := Eval cbv [split_list projT1 projT2 nbe_rewrite_rules] in split_list nbe_rewrite_rules. + Definition nbe_pr1_rewrite_rules := Eval hnf in projT1 nbe_split_rewrite_rules. + Definition nbe_pr2_rewrite_rules := Eval hnf in projT2 nbe_split_rewrite_rules. + Definition nbe_all_rewrite_rules := combine_hlist (P:=rewrite_ruleTP) nbe_pr1_rewrite_rules nbe_pr2_rewrite_rules. + + Definition arith_split_rewrite_rules := Eval cbv [split_list projT1 projT2 arith_rewrite_rules] in split_list arith_rewrite_rules. + Definition arith_pr1_rewrite_rules := Eval hnf in projT1 arith_split_rewrite_rules. + Definition arith_pr2_rewrite_rules := Eval hnf in projT2 arith_split_rewrite_rules. + Definition arith_all_rewrite_rules := combine_hlist (P:=rewrite_ruleTP) arith_pr1_rewrite_rules arith_pr2_rewrite_rules. + + Definition nbe_rewrite_head0 do_again {t} (idc : ident t) : value_with_lets t + := @assemble_identifier_rewriters nbe_dtree nbe_all_rewrite_rules do_again t idc. - Definition rewrite_head0 do_again {t} (idc : ident t) : value_with_lets t - := @assemble_identifier_rewriters dtree all_rewrite_rules do_again t idc. + Definition arith_rewrite_head0 do_again {t} (idc : ident t) : value_with_lets t + := @assemble_identifier_rewriters arith_dtree arith_all_rewrite_rules do_again t idc. Section fancy. Context (invert_low invert_high : Z (*log2wordmax*) -> Z -> option Z). @@ -1694,26 +1790,103 @@ Z.mul @@ (?x >> 128, ?y >> 128) --> mulhh @@ (x, y) Redirect "/tmp/fancy_rewrite_head" Print fancy_rewrite_head. End red_fancy. - Section red. + Section red_nbe. + Context {var : type.type base.type -> Type} + (do_again : forall t : base.type, @expr base.type ident (@Compile.value base.type ident var) (type.base t) + -> UnderLets.UnderLets base.type ident var (@expr base.type ident var (type.base t))) + {t} (idc : ident t). + + Time Let rewrite_head1 + := Eval cbv -[nbe_pr2_rewrite_rules + base.interp base.try_make_transport_cps + type.try_make_transport_cps type.try_transport_cps + UnderLets.splice UnderLets.to_expr + Compile.reflect UnderLets.reify_and_let_binds_base_cps Compile.reify Compile.reify_and_let_binds_cps + Compile.value' + SubstVarLike.is_var_fst_snd_pair_opp + ] in @nbe_rewrite_head0 var do_again t idc. + (* Finished transaction in 16.593 secs (16.567u,0.s) (successful) *) + + Time Local Definition nbe_rewrite_head2 + := Eval cbv [id + rewrite_head1 nbe_pr2_rewrite_rules + projT1 projT2 + cpsbind cpscall cps_option_bind cpsreturn + pattern.ident.arg_types + Compile.app_binding_data + Compile.app_pbase_type_interp_cps + Compile.app_ptype_interp_cps + Compile.bind_base_cps + Compile.bind_data_cps + Compile.binding_dataT + Compile.bind_value_cps + Compile.eval_decision_tree + Compile.eval_rewrite_rules + Compile.expr_of_rawexpr + Compile.lift_pbase_type_interp_cps + Compile.lift_ptype_interp_cps + Compile.lift_with_bindings + Compile.pbase_type_interp_cps + Compile.ptype_interp + Compile.ptype_interp_cps + (*Compile.reflect*) + (*Compile.reify*) + Compile.reveal_rawexpr_cps + Compile.rValueOrExpr + Compile.swap_list + Compile.type_of_rawexpr + Compile.value + (*Compile.value'*) + Compile.value_of_rawexpr + Compile.value_with_lets + Compile.with_bindingsT + ident.smart_Literal + type.try_transport_cps + rlist_rect rlist_rect_cast rwhen + ] in rewrite_head1. + (* Finished transaction in 29.683 secs (29.592u,0.048s) (successful) *) + + Local Arguments base.try_make_base_transport_cps _ !_ !_. + Local Arguments base.try_make_transport_cps _ !_ !_. + Local Arguments type.try_make_transport_cps _ _ _ !_ !_. + Local Arguments nbe_rewrite_head2 / . + + Time Definition nbe_rewrite_head + := Eval cbn [id + nbe_rewrite_head2 + cpsbind cpscall cps_option_bind cpsreturn + Compile.reify Compile.reify_and_let_binds_cps Compile.reflect Compile.value' + UnderLets.reify_and_let_binds_base_cps + UnderLets.splice UnderLets.splice_list UnderLets.to_expr + base.interp base.base_interp + type.try_make_transport_cps base.try_make_transport_cps base.try_make_base_transport_cps + PrimitiveProd.Primitive.fst PrimitiveProd.Primitive.snd Datatypes.fst Datatypes.snd + ] in nbe_rewrite_head2. + (* Finished transaction in 16.561 secs (16.54u,0.s) (successful) *) + + Redirect "/tmp/nbe_rewrite_head" Print nbe_rewrite_head. + End red_nbe. + + Section red_arith. Context {var : type.type base.type -> Type} (do_again : forall t : base.type, @expr base.type ident (@Compile.value base.type ident var) (type.base t) -> UnderLets.UnderLets base.type ident var (@expr base.type ident var (type.base t))) {t} (idc : ident t). Time Let rewrite_head1 - := Eval cbv -[pr2_rewrite_rules + := Eval cbv -[arith_pr2_rewrite_rules base.interp base.try_make_transport_cps type.try_make_transport_cps type.try_transport_cps UnderLets.splice UnderLets.to_expr Compile.reflect UnderLets.reify_and_let_binds_base_cps Compile.reify Compile.reify_and_let_binds_cps Compile.value' SubstVarLike.is_var_fst_snd_pair_opp - ] in @rewrite_head0 var do_again t idc. + ] in @arith_rewrite_head0 var do_again t idc. (* Finished transaction in 16.593 secs (16.567u,0.s) (successful) *) - Time Local Definition rewrite_head2 + Time Local Definition arith_rewrite_head2 := Eval cbv [id - rewrite_head1 pr2_rewrite_rules + rewrite_head1 arith_pr2_rewrite_rules projT1 projT2 cpsbind cpscall cps_option_bind cpsreturn pattern.ident.arg_types @@ -1753,11 +1926,11 @@ Z.mul @@ (?x >> 128, ?y >> 128) --> mulhh @@ (x, y) Local Arguments base.try_make_base_transport_cps _ !_ !_. Local Arguments base.try_make_transport_cps _ !_ !_. Local Arguments type.try_make_transport_cps _ _ _ !_ !_. - Local Arguments rewrite_head2 / . + Local Arguments arith_rewrite_head2 / . - Time Definition rewrite_head + Time Definition arith_rewrite_head := Eval cbn [id - rewrite_head2 + arith_rewrite_head2 cpsbind cpscall cps_option_bind cpsreturn Compile.reify Compile.reify_and_let_binds_cps Compile.reflect Compile.value' UnderLets.reify_and_let_binds_base_cps @@ -1765,14 +1938,16 @@ Z.mul @@ (?x >> 128, ?y >> 128) --> mulhh @@ (x, y) base.interp base.base_interp type.try_make_transport_cps base.try_make_transport_cps base.try_make_base_transport_cps PrimitiveProd.Primitive.fst PrimitiveProd.Primitive.snd Datatypes.fst Datatypes.snd - ] in rewrite_head2. + ] in arith_rewrite_head2. (* Finished transaction in 16.561 secs (16.54u,0.s) (successful) *) - Redirect "/tmp/rewrite_head" Print rewrite_head. - End red. + Redirect "/tmp/arith_rewrite_head" Print arith_rewrite_head. + End red_arith. - Definition Rewrite {t} (e : expr.Expr (ident:=ident) t) : expr.Expr (ident:=ident) t - := @Compile.Rewrite (@rewrite_head) default_fuel t e. + Definition RewriteNBE {t} (e : expr.Expr (ident:=ident) t) : expr.Expr (ident:=ident) t + := @Compile.Rewrite (@nbe_rewrite_head) nbe_default_fuel t e. + Definition RewriteArith {t} (e : expr.Expr (ident:=ident) t) : expr.Expr (ident:=ident) t + := @Compile.Rewrite (@arith_rewrite_head) arith_default_fuel t e. Definition RewriteToFancy (invert_low invert_high : Z (*log2wordmax*) -> Z -> option Z) {t} (e : expr.Expr (ident:=ident) t) : expr.Expr (ident:=ident) t @@ -1781,5 +1956,5 @@ Z.mul @@ (?x >> 128, ?y >> 128) --> mulhh @@ (x, y) Import defaults. - Definition PartialEvaluate {t} (e : Expr t) : Expr t := RewriteRules.Rewrite e. + Definition PartialEvaluate {t} (e : Expr t) : Expr t := RewriteRules.RewriteNBE e. End Compilers. diff --git a/src/Experiments/NewPipeline/StandaloneHaskellMain.v b/src/Experiments/NewPipeline/StandaloneHaskellMain.v index d9ada8451..131907bc1 100644 --- a/src/Experiments/NewPipeline/StandaloneHaskellMain.v +++ b/src/Experiments/NewPipeline/StandaloneHaskellMain.v @@ -49,6 +49,18 @@ Module UnsaturatedSolinas. (fun err => raise_failure _ (String.concat String.NewLine err))). End UnsaturatedSolinas. +Module WordByWordMontgomery. + Definition main : IO_unit + := cast_io + (argv <- getArgs; + prog <- getProgName; + ForExtraction.WordByWordMontgomery.PipelineMain + (prog::argv) + (fun res => printf_string + (String.concat "" res)) + (fun err => raise_failure _ (String.concat String.NewLine err))). +End WordByWordMontgomery. + Module SaturatedSolinas. Definition main : IO_unit := cast_io diff --git a/src/Experiments/NewPipeline/StandaloneOCamlMain.v b/src/Experiments/NewPipeline/StandaloneOCamlMain.v index 0c354b45a..c5b4db570 100644 --- a/src/Experiments/NewPipeline/StandaloneOCamlMain.v +++ b/src/Experiments/NewPipeline/StandaloneOCamlMain.v @@ -102,6 +102,15 @@ Module UnsaturatedSolinas. raise_failure. End UnsaturatedSolinas. +Module WordByWordMontgomery. + Definition main : unit + := let argv := List.map string_to_Coq_string sys_argv in + ForExtraction.WordByWordMontgomery.PipelineMain + argv + printf_list_string + raise_failure. +End WordByWordMontgomery. + Module SaturatedSolinas. Definition main : unit := let argv := List.map string_to_Coq_string sys_argv in diff --git a/src/Experiments/NewPipeline/Toplevel1.v b/src/Experiments/NewPipeline/Toplevel1.v index 1f86f656f..8a79fc852 100644 --- a/src/Experiments/NewPipeline/Toplevel1.v +++ b/src/Experiments/NewPipeline/Toplevel1.v @@ -36,6 +36,7 @@ Require Import Crypto.Util.ZUtil.AddModulo. Require Import Crypto.Util.ZUtil.CC. Require Import Crypto.Arithmetic.MontgomeryReduction.Definition. Require Import Crypto.Arithmetic.MontgomeryReduction.Proofs. +Require Import Crypto.Util.ZUtil.ModInv. Require Import Crypto.Util.ErrorT. Require Import Crypto.Util.Strings.Show. Require Import Crypto.Util.ZRange.Show. @@ -261,6 +262,230 @@ Module Ring. End ring_goal. End Ring. +(** NOTE: Module MontgomeryStyleRing SHOULD NOT depend on any compilers things *) +Module MontgomeryStyleRing. + Local Notation is_bounded_by0 r v + := ((lower r <=? v) && (v <=? upper r)). + Local Notation is_bounded_by0o r + := (match r with Some r' => fun v' => is_bounded_by0 r' v' | None => fun _ => true end). + Local Notation is_bounded_by bounds ls + := (fold_andb_map (fun r v'' => is_bounded_by0o r v'') bounds ls). + Local Notation is_bounded_by1 bounds ls + := (andb (is_bounded_by bounds (@fst _ unit ls)) true). + Local Notation is_bounded_by2 bounds ls + := (andb (is_bounded_by bounds (fst ls)) (is_bounded_by1 bounds (snd ls))). + + Lemma length_is_bounded_by bounds ls + : is_bounded_by bounds ls = true -> length ls = length bounds. + Proof. + intro H. + apply fold_andb_map_length in H; congruence. + Qed. + + Section ring_goal. + Context (limbwidth_num limbwidth_den : Z) + (n : nat) + (s : Z) + (c : list (Z * Z)) + (bounds : list (option zrange)) + (length_bounds : length bounds = n). + Local Notation weight := (weight limbwidth_num limbwidth_den). + Local Notation eval := (Positional.eval weight n). + Let prime_bound : zrange + := r[0~>(s - Associational.eval c - 1)]%zrange. + Let m := Z.to_pos (s - Associational.eval c). + Context (m_eq : Z.pos m = s - Associational.eval c) + (sc_pos : 0 < s - Associational.eval c) + (valid : list Z -> Prop) + (from_montgomery_mod : list Z -> list Z) + (Hfrom_montgomery_mod + : forall v, valid v -> valid (from_montgomery_mod v)) + (Interp_rfrom_montgomeryv : list Z -> list Z) + (HInterp_rfrom_montgomeryv : forall arg, + is_bounded_by1 bounds arg = true + -> is_bounded_by bounds (Interp_rfrom_montgomeryv (fst arg)) = true + /\ Interp_rfrom_montgomeryv (fst arg) = from_montgomery_mod (fst arg)) + (mulmod : list Z -> list Z -> list Z) + (Hmulmod + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (mulmod a b)) mod (s - Associational.eval c) + = (eval (from_montgomery_mod a) * eval (from_montgomery_mod b)) mod (s - Associational.eval c)) + /\ (forall a (_ : valid a) b (_ : valid b), valid (mulmod a b))) + (Interp_rmulv : list Z -> list Z -> list Z) + (HInterp_rmulv : forall arg, + is_bounded_by2 bounds arg = true + -> is_bounded_by bounds (Interp_rmulv (fst arg) (fst (snd arg))) = true + /\ Interp_rmulv (fst arg) (fst (snd arg)) = mulmod (fst arg) (fst (snd arg))) + (addmod : list Z -> list Z -> list Z) + (Haddmod + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (addmod a b)) mod (s - Associational.eval c) + = (eval (from_montgomery_mod a) + eval (from_montgomery_mod b)) mod (s - Associational.eval c)) + /\ (forall a (_ : valid a) b (_ : valid b), valid (addmod a b))) + (Interp_raddv : list Z -> list Z -> list Z) + (HInterp_raddv : forall arg, + is_bounded_by2 bounds arg = true + -> is_bounded_by bounds (Interp_raddv (fst arg) (fst (snd arg))) = true + /\ Interp_raddv (fst arg) (fst (snd arg)) = addmod (fst arg) (fst (snd arg))) + (submod : list Z -> list Z -> list Z) + (Hsubmod + : (forall a (_ : valid a) b (_ : valid b), eval (from_montgomery_mod (submod a b)) mod (s - Associational.eval c) + = (eval (from_montgomery_mod a) - eval (from_montgomery_mod b)) mod (s - Associational.eval c)) + /\ (forall a (_ : valid a) b (_ : valid b), valid (submod a b))) + (Interp_rsubv : list Z -> list Z -> list Z) + (HInterp_rsubv : forall arg, + is_bounded_by2 bounds arg = true + -> is_bounded_by bounds (Interp_rsubv (fst arg) (fst (snd arg))) = true + /\ Interp_rsubv (fst arg) (fst (snd arg)) = submod (fst arg) (fst (snd arg))) + (oppmod : list Z -> list Z) + (Hoppmod + : (forall a (_ : valid a), eval (from_montgomery_mod (oppmod a)) mod (s - Associational.eval c) + = (-eval (from_montgomery_mod a)) mod (s - Associational.eval c)) + /\ (forall a (_ : valid a), valid (oppmod a))) + (Interp_roppv : list Z -> list Z) + (HInterp_roppv : forall arg, + is_bounded_by1 bounds arg = true + -> is_bounded_by bounds (Interp_roppv (fst arg)) = true + /\ Interp_roppv (fst arg) = oppmod (fst arg)) + (zeromod : list Z) + (Hzeromod + : (eval (from_montgomery_mod zeromod)) mod (s - Associational.eval c) + = 0 mod (s - Associational.eval c) + /\ valid zeromod) + (Interp_rzerov : list Z) + (HInterp_rzerov : is_bounded_by bounds Interp_rzerov = true + /\ Interp_rzerov = zeromod) + (onemod : list Z) + (Honemod + : (eval (from_montgomery_mod onemod)) mod (s - Associational.eval c) + = 1 mod (s - Associational.eval c) + /\ valid onemod) + (Interp_ronev : list Z) + (HInterp_ronev : is_bounded_by bounds Interp_ronev = true + /\ Interp_ronev = onemod) + (encodemod : Z -> list Z) + (Hencodemod + : (forall v, 0 <= v < s - Associational.eval c -> eval (from_montgomery_mod (encodemod v)) mod (s - Associational.eval c) = v mod (s - Associational.eval c)) + /\ (forall v, 0 <= v < s - Associational.eval c -> valid (encodemod v))) + (Interp_rencodev : Z -> list Z) + (HInterp_rencodev : forall arg, + is_bounded_by0 prime_bound (@fst _ unit arg) && true = true + -> is_bounded_by bounds (Interp_rencodev (fst arg)) = true + /\ Interp_rencodev (fst arg) = encodemod (fst arg)). + + Local Notation T := (list Z) (only parsing). + Local Notation encoded_ok ls + := (is_bounded_by bounds ls = true /\ valid ls) (only parsing). + Local Notation encoded_okf := (fun ls => encoded_ok ls) (only parsing). + + Definition Fdecode (v : T) : F m + := F.of_Z m (Positional.eval weight n (Interp_rfrom_montgomeryv v)). + Definition T_eq (x y : T) + := Fdecode x = Fdecode y. + + Definition encodedT := sig encoded_okf. + + Definition ring_mul (x y : T) : T + := Interp_rmulv x y. + Definition ring_add (x y : T) : T := Interp_raddv x y. + Definition ring_sub (x y : T) : T := Interp_rsubv x y. + Definition ring_opp (x : T) : T := Interp_roppv x. + Definition ring_encode (x : F m) : T := Interp_rencodev (F.to_Z x). + + Definition GoodT : Prop + := @subsetoid_ring + (list Z) encoded_okf T_eq + Interp_rzerov Interp_ronev ring_opp ring_add ring_sub ring_mul + /\ @is_subsetoid_homomorphism + (F m) (fun _ => True) eq 1%F F.add F.mul + (list Z) encoded_okf T_eq Interp_ronev ring_add ring_mul ring_encode + /\ @is_subsetoid_homomorphism + (list Z) encoded_okf T_eq Interp_ronev ring_add ring_mul + (F m) (fun _ => True) eq 1%F F.add F.mul + Fdecode. + + Hint Rewrite ->@F.to_Z_add : push_FtoZ. + Hint Rewrite ->@F.to_Z_mul : push_FtoZ. + Hint Rewrite ->@F.to_Z_opp : push_FtoZ. + Hint Rewrite ->@F.to_Z_of_Z : push_FtoZ. + + Lemma Fm_bounded_alt (x : F m) + : (0 <=? F.to_Z x) && (F.to_Z x <=? Z.pos m - 1) = true. + Proof using m_eq. + clear -m_eq. + destruct x as [x H]; cbn [F.to_Z proj1_sig]. + pose proof (Z.mod_pos_bound x (Z.pos m)). + rewrite andb_true_iff; split; Z.ltb_to_lt; lia. + Qed. + + Lemma Fm_bounded_alt' (x : F m) + : 0 <= F.to_Z x < Z.pos m. + Proof using m_eq. + clear -m_eq. + destruct x as [x H]; cbn [F.to_Z proj1_sig]. + pose proof (Z.mod_pos_bound x (Z.pos m)). + split; Z.ltb_to_lt; lia. + Qed. + + Lemma Good : GoodT. + Proof. + split_and. + repeat match goal with + | [ H : context[andb _ true] |- _ ] => setoid_rewrite andb_true_r in H + end. + eapply subsetoid_ring_by_ring_isomorphism; + cbv [ring_opp ring_add ring_sub ring_mul ring_encode F.sub] in *; + repeat match goal with + | [ H : forall arg : _ * unit, _ |- _ ] => specialize (fun arg => H (arg, tt)) + | [ H : forall arg : _ * (_ * unit), _ |- _ ] => specialize (fun a b => H (a, (b, tt))) + | _ => progress cbn [fst snd] in * + | _ => solve [ auto using andb_true_intro, conj with nocore ] + | _ => progress intros + | [ H : is_bounded_by _ _ = true /\ _ |- _ ] => destruct H + | [ |- is_bounded_by _ _ = true /\ _ ] => split + | [ H : _ |- is_bounded_by _ _ = true ] => apply H + | [ H : _ |- valid _ ] => rewrite H + | [ H : context[valid _] |- valid _ ] => apply H + | [ |- _ <-> _ ] => reflexivity + | [ |- ?x = ?x ] => reflexivity + | [ |- _ = _ :> Z ] => first [ reflexivity | rewrite <- m_eq; reflexivity ] + | [ H : context[?x] |- Fdecode ?x = _ ] => rewrite H + | [ H : context[?x _] |- Fdecode (?x _) = _ ] => rewrite H + | [ H : context[?x _ _] |- Fdecode (?x _ _) = _ ] => rewrite H + | _ => progress cbv [Fdecode] + | [ |- _ = _ :> F _ ] => apply F.eq_to_Z_iff + | _ => progress autorewrite with push_FtoZ + | _ => rewrite m_eq + | [ H : context[?f (?x _ _)] |- context[eval (?f (?x _ _))] ] => rewrite H + | [ H : context[?f (?x _)] |- context[eval (?f (?x _))] ] => rewrite H + | [ H : context[?f ?x] |- context[eval (?f ?x)] ] => rewrite H + | [ H : context[?x _ _] |- context[eval (?x _ _)] ] => rewrite H + | [ H : context[?x _] |- context[eval (?x _)] ] => rewrite H + | [ H : context[?x] |- context[eval ?x] ] => rewrite H + | [ H : context[?y _ _ = ?x _ _], H' : context[is_bounded_by _ (?y _ _) = true] + |- is_bounded_by _ (?x _ _) = true ] + => rewrite <- H; [ apply H' | .. ] + | [ H : context[?y _ = ?x _], H' : context[is_bounded_by _ (?y _) = true] + |- is_bounded_by _ (?x _) = true ] + => rewrite <- H; [ apply H' | .. ] + | [ H : context[?y = ?x], H' : context[is_bounded_by _ ?y = true] + |- is_bounded_by _ ?x = true ] + => rewrite <- H; [ apply H' | .. ] + | [ |- context[List.length ?x] ] + => erewrite (length_is_bounded_by _ x) + by eauto using andb_true_intro, conj with nocore + | [ |- _ = _ :> Z ] + => push_Zmod; reflexivity + | _ => pull_Zmod; rewrite Z.add_opp_r + | _ => rewrite expanding_id_id + | [ |- context[F.to_Z _ mod (_ - _)] ] + => rewrite <- m_eq, F.mod_to_Z + | _ => rewrite <- m_eq; apply Fm_bounded_alt + | _ => rewrite <- m_eq; apply Fm_bounded_alt' + | [ |- context[andb _ true] ] => rewrite andb_true_r + end. + Qed. + End ring_goal. +End MontgomeryStyleRing. + Import Associational Positional. Import @@ -289,13 +514,14 @@ Notation "x" := (expr.Var x) (only printing, at level 9) : expr_scope. Axiom admit_pf : False. Notation admit := (match admit_pf with end). + Module Pipeline. Import GeneralizeVar. Inductive ErrorMessage := | Computed_bounds_are_not_tight_enough {t} (computed_bounds expected_bounds : ZRange.type.base.option.interp (type.final_codomain t)) (syntax_tree : Expr t) (arg_bounds : type.for_each_lhs_of_arrow ZRange.type.option.interp t) - | Type_too_complicated_for_cps (t : type) + | No_modular_inverse (descr : string) (v : Z) (m : Z) | Value_not_leZ (descr : string) (lhs rhs : Z) | Value_not_leQ (descr : string) (lhs rhs : Q) | Value_not_ltZ (descr : string) (lhs rhs : Z) @@ -395,8 +621,8 @@ Module Pipeline. => (["(Unprintible syntax tree used in bounds analysis)" ++ String.NewLine]%string) ++ ["Stringification failed on the syntax tree:"] ++ show_lines false syntax_tree ++ [errs] end)%list - | Type_too_complicated_for_cps t - => ["Type too complicated for cps: " ++ show false t] + | No_modular_inverse descr v m + => ["Could not compute a modular inverse (" ++ descr ++ ") for " ++ show false v ++ " mod " ++ show false m] | Value_not_leZ descr lhs rhs => ["Value not ≤ (" ++ descr ++ ") : expected " ++ show false lhs ++ " ≤ " ++ show false rhs] | Value_not_leQ descr lhs rhs @@ -437,6 +663,7 @@ Module Pipeline. := (*let E := expr.Uncurry E in*) let E := PartialEvaluateWithListInfoFromBounds E arg_bounds in let E := PartialEvaluate E in + let E := RewriteRules.RewriteArith E in (* Note that DCE evaluates the expr with two different [var] arguments, and so results in a pipeline that is 2x slower unless we pass through a uniformly concrete [var] type @@ -448,7 +675,10 @@ Module Pipeline. let E := FromFlat e in let E := if with_subst01 then Subst01.Subst01 E else E in let E := UnderLets.LetBindReturn E in - let E := PartialEvaluate E in (* after inlining, see if any new rewrite redexes are available *) + let E := RewriteRules.RewriteArith E in (* after inlining, see if any new rewrite redexes are available *) + dlet_nd e := ToFlat E in + let E := FromFlat e in + let E := if with_dead_code_elimination then DeadCodeElimination.EliminateDead E else E in let E := ReassociateSmallConstants.Reassociate (2^8) E in let E := match translate_to_fancy with | Some {| invert_low := invert_low ; invert_high := invert_high |} => RewriteRules.RewriteToFancy invert_low invert_high E @@ -823,12 +1053,12 @@ Derive to_bytes_gen (bitwidth : Z) (m_enc : list Z) (f : list Z), - Interp (t:=reify_type_of to_bytesmod) + Interp (t:=reify_type_of freeze_to_bytesmod) to_bytes_gen limbwidth_num limbwidth_den n bitwidth m_enc f - = to_bytesmod limbwidth_num limbwidth_den n bitwidth m_enc f) + = freeze_to_bytesmod limbwidth_num limbwidth_den n bitwidth m_enc f) As to_bytes_gen_correct. Proof. cache_reify (). Qed. -Hint Extern 1 (_ = to_bytesmod _ _ _ _ _ _) => simple apply to_bytes_gen_correct : reify_gen_cache. +Hint Extern 1 (_ = freeze_to_bytesmod _ _ _ _ _ _) => simple apply to_bytes_gen_correct : reify_gen_cache. Derive from_bytes_gen SuchThat (forall (limbwidth_num limbwidth_den : Z) @@ -1152,7 +1382,7 @@ Module Import UnsaturatedSolinas. := BoundsPipeline_with_bytes_no_subst01_correct (Some tight_bounds, tt) prime_bytes_bounds - (to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc). + (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc). Definition srfrom_bytes prefix := BoundsPipelineToStrings_with_bytes_no_subst01 @@ -1373,8 +1603,8 @@ Module Import UnsaturatedSolinas. (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=to_bytesT) (@ZRange.type.option.is_bounded_by) (Some tight_bounds, tt) f = true), ((ZRange.type.base.option.is_bounded_by prime_bytes_bounds (type.app_curried (Interp rto_bytesv) f) = true /\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rto_bytesv) f - = type.app_curried (t:=to_bytesT) (to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) - /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) = (Positional.eval (weight (Qnum limbwidth) (Z.pos (Qden limbwidth))) n (fst f) mod m))). + = type.app_curried (t:=to_bytesT) (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) + /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (freeze_to_bytesmod (Qnum limbwidth) (Z.pos (Qden limbwidth)) n machine_wordsize m_enc) f)) = (Positional.eval (weight (Qnum limbwidth) (Z.pos (Qden limbwidth))) n (fst f) mod m))). (** XXX TODO MOVE ME *) Lemma fold_andb_map_snoc A B f x xs y ys @@ -1448,7 +1678,7 @@ Module Import UnsaturatedSolinas. { apply Hto_bytesv; assumption. } { cbn [type.for_each_lhs_of_arrow type_base type.andb_bool_for_each_lhs_of_arrow ZRange.type.option.is_bounded_by fst snd] in *. rewrite Bool.andb_true_iff in *; split_and'. - etransitivity; [ apply eval_to_bytesmod | f_equal; (eassumption || (symmetry; eassumption)) ]; + etransitivity; [ apply eval_freeze_to_bytesmod | f_equal; (eassumption || (symmetry; eassumption)) ]; auto; try omega. { erewrite Ring.length_is_bounded_by by eassumption; assumption. } { lazymatch goal with @@ -1834,6 +2064,739 @@ Goal False. Abort. *) +Module WordByWordMontgomery. + Import Arithmetic.WordByWordMontgomery. + Derive mul_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z) + (f g : list Z), + Interp (t:=reify_type_of mulmod) + mul_gen bitwidth n m m' f g + = mulmod bitwidth n m m' f g) + As mul_gen_correct. + Proof. Time cache_reify (). Time Qed. + Hint Extern 1 (_ = mulmod _ _ _ _ _ _) => simple apply mul_gen_correct : reify_gen_cache. + + Derive square_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z) + (f : list Z), + Interp (t:=reify_type_of squaremod) + square_gen bitwidth n m m' f + = squaremod bitwidth n m m' f) + As square_gen_correct. + Proof. + Time cache_reify (). + (* we would do something faster, but it breaks extraction COQBUG(https://github.com/coq/coq/issues/7954) *) + (* + intros; etransitivity; [ | cbv [squaremod]; apply mul_gen_correct ]. + subst square_gen. + instantiate (1:=ltac:(let r := Reify (fun F (bitwidth:Z) (n:nat) (m m' : Z) (f : list Z) => (F bitwidth n m m' f f):list Z) in refine (r @ mul_gen)%Expr)). + reflexivity. + *) + Time Qed. + Hint Extern 1 (_ = squaremod _ _ _ _ _) => simple apply square_gen_correct : reify_gen_cache. + + Derive encode_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z) + (v : Z), + Interp (t:=reify_type_of encodemod) + encode_gen bitwidth n m m' v + = encodemod bitwidth n m m' v) + As encode_gen_correct. + Proof. + Time cache_reify (). + (* we would do something faster, but it breaks extraction COQBUG(https://github.com/coq/coq/issues/7954) *) + (* + intros; etransitivity; [ | cbv [encodemod]; apply mul_gen_correct ]. + subst encode_gen; revert bitwidth n m m' v. + lazymatch goal with + | [ |- forall bw n m m' v, ?interp ?ev bw n m m' v = ?interp' mul_gen bw n m m' (@?A bw n m m' v) (@?B bw n m m' v) ] + => let rv := constr:(fun F bw n m m' v => (F bw n m m' (A bw n m m' v) (B bw n m m' v)):list Z) in + intros; + instantiate (1:=ltac:(let r := Reify rv in + refine (r @ mul_gen)%Expr)) + end. + reflexivity. + *) + Time Qed. + Hint Extern 1 (_ = encodemod _ _ _ _ _) => simple apply encode_gen_correct : reify_gen_cache. + + Derive add_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (f g : list Z), + Interp (t:=reify_type_of addmod) + add_gen bitwidth n m f g + = addmod bitwidth n m f g) + As add_gen_correct. + Proof. Time cache_reify (). Time Qed. + Hint Extern 1 (_ = addmod _ _ _ _ _) => simple apply add_gen_correct : reify_gen_cache. + + Derive sub_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (f g : list Z), + Interp (t:=reify_type_of submod) + sub_gen bitwidth n m f g + = submod bitwidth n m f g) + As sub_gen_correct. + Proof. Time cache_reify (). Time Qed. + Hint Extern 1 (_ = submod _ _ _ _ _) => simple apply sub_gen_correct : reify_gen_cache. + + Derive opp_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (f : list Z), + Interp (t:=reify_type_of oppmod) + opp_gen bitwidth n m f + = oppmod bitwidth n m f) + As opp_gen_correct. + Proof. Time cache_reify (). Time Qed. + Hint Extern 1 (_ = oppmod _ _ _ _) => simple apply opp_gen_correct : reify_gen_cache. + + Derive from_montgomery_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z) + (f : list Z), + Interp (t:=reify_type_of from_montgomery_mod) + from_montgomery_gen bitwidth n m m' f + = from_montgomery_mod bitwidth n m m' f) + As from_montgomery_gen_correct. + Proof. + Time cache_reify (). + (* we would do something faster, but it breaks extraction COQBUG(https://github.com/coq/coq/issues/7954) *) + (* + intros; etransitivity; [ | cbv [from_montgomery_mod]; apply mul_gen_correct ]. + subst from_montgomery_gen. + instantiate (1:=ltac:(let r := Reify (fun F (bitwidth:Z) (n:nat) (m m' : Z) (f : list Z) => (F bitwidth n m m' f (onemod bitwidth n)):list Z) in refine (r @ mul_gen)%Expr)). + reflexivity. + *) + Qed. + Hint Extern 1 (_ = from_montgomery_mod _ _ _ _ _) => simple apply from_montgomery_gen_correct : reify_gen_cache. + + Definition zeromod bitwidth n m m' := encodemod bitwidth n m m' 0. + Definition onemod bitwidth n m m' := encodemod bitwidth n m m' 1. + Derive zero_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z), + Interp (t:=reify_type_of zeromod) + zero_gen bitwidth n m m' + = zeromod bitwidth n m m') + As zero_gen_correct. + Proof. + (* Time cache_reify (). *) + (* we do something faster *) + intros; etransitivity; [ | cbv [zeromod]; apply encode_gen_correct ]. + subst zero_gen. + instantiate (1:=ltac:(let r := Reify (fun F (bitwidth:Z) (n:nat) (m m' : Z) => (F bitwidth n m m' 0):list Z) in refine (r @ encode_gen)%Expr)). + reflexivity. + Qed. + Hint Extern 1 (_ = zeromod _ _ _ _) => simple apply zero_gen_correct : reify_gen_cache. + + Derive one_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (m : Z) + (m' : Z), + Interp (t:=reify_type_of onemod) + one_gen bitwidth n m m' + = onemod bitwidth n m m') + As one_gen_correct. + Proof. + (* Time cache_reify (). *) + (* we do something faster *) + intros; etransitivity; [ | cbv [onemod]; apply encode_gen_correct ]. + subst one_gen. + instantiate (1:=ltac:(let r := Reify (fun F (bitwidth:Z) (n:nat) (m m' : Z) => (F bitwidth n m m' 1):list Z) in refine (r @ encode_gen)%Expr)). + reflexivity. + Qed. + Hint Extern 1 (_ = onemod _ _ _ _) => simple apply one_gen_correct : reify_gen_cache. + + Derive nonzero_gen + SuchThat (forall (f : list Z), + Interp (t:=reify_type_of nonzeromod) + nonzero_gen f + = nonzeromod f) + As nonzero_gen_correct. + Proof. Time cache_reify (). Time Qed. + Hint Extern 1 (_ = nonzeromod _) => simple apply nonzero_gen_correct : reify_gen_cache. + + Derive to_bytes_gen + SuchThat (forall (bitwidth : Z) + (n : nat) + (f : list Z), + Interp (t:=reify_type_of to_bytesmod) + to_bytes_gen bitwidth n f + = to_bytesmod bitwidth n f) + As to_bytes_gen_correct. + Proof. cache_reify (). Qed. + Hint Extern 1 (_ = to_bytesmod _ _ _) => simple apply to_bytes_gen_correct : reify_gen_cache. + + Section rcarry_mul. + Context (s : Z) + (c : list (Z * Z)) + (machine_wordsize : Z). + + Let n : nat := Z.to_nat (Qceiling (Z.log2_up s / machine_wordsize)). + Let m := s - Associational.eval c. + Let r := 2^machine_wordsize. + Let r' := match Z.modinv r m with + | Some r' => r' + | None => 0 + end. + Let m' := match Z.modinv (-m) r with + | Some m' => m' + | None => 0 + end. + Let n_bytes := bytes_n machine_wordsize 1 n. + Let prime_upperbound_list : list Z + := encode (UniformWeight.uweight machine_wordsize) n s c (s-1). + Let prime_bytes_upperbound_list : list Z + := encode (weight 8 1) n_bytes s c (s-1). + Let upperbounds : list Z := prime_upperbound_list. + Definition prime_bound : ZRange.type.option.interp (base.type.Z) + := Some r[0~>(s - Associational.eval c - 1)]%zrange. + Definition prime_bounds : ZRange.type.option.interp (base.type.list (base.type.Z)) + := Some (List.map (fun v => Some r[0 ~> v]%zrange) prime_upperbound_list). + Definition prime_bytes_bounds : ZRange.type.option.interp (base.type.list (base.type.Z)) + := Some (List.map (fun v => Some r[0 ~> v]%zrange) prime_bytes_upperbound_list). + Definition saturated_bounds : ZRange.type.option.interp (base.type.list (base.type.Z)) + := Some (List.repeat (Some r[0 ~> 2^machine_wordsize-1]%zrange) n). + + Definition m_enc : list Z + := encode (UniformWeight.uweight machine_wordsize) n s c (s-Associational.eval c). + + Definition relax_zrange_of_machine_wordsize + := relax_zrange_gen [1; machine_wordsize; 2 * machine_wordsize]%Z. + + Definition relax_zrange_of_machine_wordsize_with_bytes + := relax_zrange_gen [1; 8; machine_wordsize; 2 * machine_wordsize]%Z. + + Let relax_zrange := relax_zrange_of_machine_wordsize. + Let relax_zrange_with_bytes := relax_zrange_of_machine_wordsize_with_bytes. + Definition bounds : list (ZRange.type.option.interp base.type.Z) + := Option.invert_Some saturated_bounds (*List.map (fun u => Some r[0~>u]%zrange) upperbounds*). + + (** Note: If you change the name or type signature of this + function, you will need to update the code in CLI.v *) + Definition check_args {T} (res : Pipeline.ErrorT T) + : Pipeline.ErrorT T + := fold_right + (fun '(b, e) k => if b:bool then Error e else k) + res + [(negb (1 d) _). + + Notation BoundsPipelineToStrings prefix name comment rop in_bounds out_bounds + := ((prefix ++ name)%string, + Pipeline.BoundsPipelineToStrings + true (* static *) prefix (prefix ++ name)%string comment%string%list + (*false*) true None + relax_zrange + rop%Expr in_bounds out_bounds). + + Notation BoundsPipeline_correct in_bounds out_bounds op + := (fun rv (rop : Expr (reify_type_of op)) Hrop + => @Pipeline.BoundsPipeline_correct_trans + (*false*) true None + relax_zrange + (relax_zrange_gen_good _) + _ + rop + in_bounds + out_bounds + op + Hrop rv) + (only parsing). + + Notation BoundsPipelineToStrings_no_subst01 prefix name comment rop in_bounds out_bounds + := ((prefix ++ name)%string, + Pipeline.BoundsPipelineToStrings + true (* static *) prefix (prefix ++ name)%string comment%string%list + (*false*) false None + relax_zrange + rop%Expr in_bounds out_bounds). + + Notation BoundsPipeline_no_subst01_correct in_bounds out_bounds op + := (fun rv (rop : Expr (reify_type_of op)) Hrop + => @Pipeline.BoundsPipeline_correct_trans + (*false*) false None + relax_zrange + (relax_zrange_gen_good _) + _ + rop + in_bounds + out_bounds + op + Hrop rv) + (only parsing). + + Notation BoundsPipelineToStrings_with_bytes_no_subst01 prefix name comment rop in_bounds out_bounds + := ((prefix ++ name)%string, + Pipeline.BoundsPipelineToStrings + true (* static *) prefix (prefix ++ name)%string comment%string%list + (*false*) false None + relax_zrange_with_bytes + rop%Expr in_bounds out_bounds). + + Notation BoundsPipeline_with_bytes_no_subst01_correct in_bounds out_bounds op + := (fun rv (rop : Expr (reify_type_of op)) Hrop + => @Pipeline.BoundsPipeline_correct_trans + (*false*) false None + relax_zrange_with_bytes + (relax_zrange_gen_good _) + _ + rop + in_bounds + out_bounds + op + Hrop rv) + (only parsing). + + (* N.B. We only need [rmul] if we want to extract the Pipeline; otherwise we can just use [rmul_correct] *) + Definition srmul prefix + := BoundsPipelineToStrings_no_subst01 + prefix "mul" [] + (mul_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m @ GallinaReify.Reify m') + (Some bounds, (Some bounds, tt)) + (Some bounds). + + Definition rmul_correct + := BoundsPipeline_no_subst01_correct + (Some bounds, (Some bounds, tt)) + (Some bounds) + (mulmod machine_wordsize n m m'). + + Definition srsquare prefix + := BoundsPipelineToStrings_no_subst01 + prefix "square" [] + (square_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m @ GallinaReify.Reify m') + (Some bounds, tt) + (Some bounds). + + Definition rsquare_correct + := BoundsPipeline_no_subst01_correct + (Some bounds, tt) + (Some bounds) + (squaremod machine_wordsize n m m'). + + Definition sradd prefix + := BoundsPipelineToStrings + prefix "add" [] + (add_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m) + (Some bounds, (Some bounds, tt)) + (Some bounds). + + Definition radd_correct + := BoundsPipeline_correct + (Some bounds, (Some bounds, tt)) + (Some bounds) + (addmod machine_wordsize n m). + + Definition srsub prefix + := BoundsPipelineToStrings + prefix "sub" [] + (sub_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m) + (Some bounds, (Some bounds, tt)) + (Some bounds). + + Definition rsub_correct + := BoundsPipeline_correct + (Some bounds, (Some bounds, tt)) + (Some bounds) + (submod machine_wordsize n m). + + Definition sropp prefix + := BoundsPipelineToStrings + prefix "opp" [] + (opp_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m) + (Some bounds, tt) + (Some bounds). + + Definition ropp_correct + := BoundsPipeline_correct + (Some bounds, tt) + (Some bounds) + (oppmod machine_wordsize n m). + + Definition srfrom_montgomery prefix + := BoundsPipelineToStrings + prefix "from_montgomery" [] + (from_montgomery_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n @ GallinaReify.Reify m @ GallinaReify.Reify m') + (Some bounds, tt) + (Some bounds). + + Definition rfrom_montgomery_correct + := BoundsPipeline_correct + (Some bounds, tt) + (Some bounds) + (from_montgomery_mod machine_wordsize n m m'). + + Definition srnonzero prefix + := BoundsPipelineToStrings + prefix "nonzero" [] + nonzero_gen + (Some bounds, tt) + (Some r[0~>r-1]%zrange). + + Definition rnonzero_correct + := BoundsPipeline_correct + (Some bounds, tt) + (Some r[0~>r-1]%zrange) + nonzeromod. + + Definition srselectznz prefix + := BoundsPipelineToStrings_with_bytes_no_subst01 + prefix "selectznz" [] + selectznz_gen + (Some r[0~>1], (saturated_bounds, (saturated_bounds, tt)))%zrange + saturated_bounds. + + Definition rselectznz_correct + := BoundsPipeline_with_bytes_no_subst01_correct + (Some r[0~>1], (saturated_bounds, (saturated_bounds, tt)))%zrange + saturated_bounds + Positional.select. + + Definition srto_bytes prefix + := BoundsPipelineToStrings_with_bytes_no_subst01 + prefix "to_bytes" [] + (to_bytes_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify n) + (prime_bounds, tt) + prime_bytes_bounds. + + Definition rto_bytes_correct + := BoundsPipeline_with_bytes_no_subst01_correct + (prime_bounds, tt) + prime_bytes_bounds + (to_bytesmod machine_wordsize n). + + Definition srfrom_bytes prefix + := BoundsPipelineToStrings_with_bytes_no_subst01 + prefix "from_bytes" [] + (from_bytes_gen + @ GallinaReify.Reify machine_wordsize @ GallinaReify.Reify 1 @ GallinaReify.Reify n) + (prime_bytes_bounds, tt) + prime_bounds. + + Definition rfrom_bytes_correct + := BoundsPipeline_with_bytes_no_subst01_correct + (prime_bytes_bounds, tt) + prime_bounds + (from_bytesmod machine_wordsize 1 n). + + Definition rencode_correct + := BoundsPipeline_correct + (prime_bound, tt) + (Some bounds) + (encodemod machine_wordsize n m m'). + + Definition rzero_correct + := BoundsPipeline_correct + tt + (Some bounds) + (zeromod machine_wordsize n m m'). + + Definition rone_correct + := BoundsPipeline_correct + tt + (Some bounds) + (onemod machine_wordsize n m m'). + + Notation srmulx := (srmulx machine_wordsize). + Notation srmulx_correct := (srmulx_correct machine_wordsize). + Notation sraddcarryx := (sraddcarryx machine_wordsize). + Notation sraddcarryx_correct := (sraddcarryx_correct machine_wordsize). + Notation srsubborrowx := (srsubborrowx machine_wordsize). + Notation srsubborrowx_correct := (srsubborrowx_correct machine_wordsize). + Notation srcmovznz := (srcmovznz machine_wordsize). + Notation srcmovznz_correct := (srcmovznz_correct machine_wordsize). + + (* we need to strip off [Hrv : ... = Pipeline.Success rv] and related arguments *) + Definition rmul_correctT rv : Prop + := type_of_strip_3arrow (@rmul_correct rv). + Definition rsquare_correctT rv : Prop + := type_of_strip_3arrow (@rsquare_correct rv). + Definition radd_correctT rv : Prop + := type_of_strip_3arrow (@radd_correct rv). + Definition rsub_correctT rv : Prop + := type_of_strip_3arrow (@rsub_correct rv). + Definition rfrom_montgomery_correctT rv : Prop + := type_of_strip_3arrow (@rfrom_montgomery_correct rv). + Definition ropp_correctT rv : Prop + := type_of_strip_3arrow (@ropp_correct rv). + Definition rnonzero_correctT rv : Prop + := type_of_strip_3arrow (@rnonzero_correct rv). + Definition rselectznz_correctT rv : Prop + := type_of_strip_3arrow (@rselectznz_correct rv). + Definition rto_bytes_correctT rv : Prop + := type_of_strip_3arrow (@rto_bytes_correct rv). + Definition rfrom_bytes_correctT rv : Prop + := type_of_strip_3arrow (@rfrom_bytes_correct rv). + Definition rencode_correctT rv : Prop + := type_of_strip_3arrow (@rencode_correct rv). + Definition rzero_correctT rv : Prop + := type_of_strip_3arrow (@rzero_correct rv). + Definition rone_correctT rv : Prop + := type_of_strip_3arrow (@rone_correct rv). + + Section make_ring. + Let mv : positive := Z.to_pos (s - Associational.eval c). + Context (curve_good : check_args (Success tt) = Success tt) + {rmulv} (Hrmulv : rmul_correctT rmulv) + {raddv} (Hraddv : radd_correctT raddv) + {rsubv} (Hrsubv : rsub_correctT rsubv) + {rfrom_montgomeryv} (Hrfrom_montgomeryv : rfrom_montgomery_correctT rfrom_montgomeryv) + {roppv} (Hroppv : ropp_correctT roppv) + {rzerov} (Hrzerov : rzero_correctT rzerov) + {ronev} (Hronev : rone_correctT ronev) + {rencodev} (Hrencodev : rencode_correctT rencodev) + {rnonzerov} (Hrnonzerov : rnonzero_correctT rnonzerov) + {rto_bytesv} (Hto_bytesv : rto_bytes_correctT rto_bytesv) + {rfrom_bytesv} (Hfrom_bytesv : rfrom_bytes_correctT rfrom_bytesv). + + Local Ltac use_curve_good_t := + repeat first [ assumption + | progress rewrite ?map_length, ?Z.mul_0_r, ?Pos.mul_1_r, ?Z.mul_1_r in * + | reflexivity + | lia + | rewrite interp_reify_list, ?map_map + | rewrite map_ext with (g:=id), map_id + | progress distr_length + | progress cbv [Qceiling Qfloor Qopp Qdiv Qplus inject_Z Qmult Qinv] in * + | progress cbv [Qle] in * + | progress cbn -[reify_list] in * + | progress intros + | solve [ auto ] ]. + + Lemma use_curve_good + : Z.pos mv = s - Associational.eval c + /\ Z.pos mv <> 0 + /\ s - Associational.eval c <> 0 + /\ s <> 0 + /\ 0 < machine_wordsize + /\ n <> 0%nat + /\ List.length bounds = n + /\ List.length bounds = n + /\ 0 < 1 <= machine_wordsize + /\ 0 < Associational.eval c < s + /\ (r * r') mod m = 1 + /\ (m * m') mod r = (-1) mod r + /\ 0 < machine_wordsize + /\ 1 < m + /\ m < r^n. + Proof. + clear -curve_good. + cbv [check_args fold_right] in curve_good. + cbv [bounds prime_bound m_enc prime_bounds] in *. + break_innermost_match_hyps; try discriminate. + rewrite negb_false_iff in *. + Z.ltb_to_lt. + rewrite NPeano.Nat.eqb_neq in *. + intros. + cbv [Qnum Qden Qceiling Qfloor Qopp Qdiv Qplus inject_Z Qmult Qinv] in *. + rewrite ?map_length, ?Z.mul_0_r, ?Pos.mul_1_r, ?Z.mul_1_r in *. + specialize_by lia. + repeat match goal with H := _ |- _ => subst H end. + repeat match goal with + | [ H : list_beq _ _ _ _ = true |- _ ] => apply internal_list_dec_bl in H; [ | intros; Z.ltb_to_lt; omega.. ] + end. + repeat apply conj. + { destruct (s - Associational.eval c) eqn:?; cbn; lia. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + { use_curve_good_t. } + Qed. + + (** TODO: Find a better place to put the spec for [to_bytes] *) + Definition GoodT : Prop + := @MontgomeryStyleRing.GoodT + machine_wordsize 1 + n s c + bounds + (valid machine_wordsize n m) + (Interp rfrom_montgomeryv) + (Interp rmulv) + (Interp raddv) + (Interp rsubv) + (Interp roppv) + (Interp rzerov) + (Interp ronev) + (Interp rencodev) + /\ (let to_bytesT := (base.type.list base.type.Z -> base.type.list base.type.Z)%etype in + forall f + (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=to_bytesT) (@ZRange.type.option.is_bounded_by) (prime_bounds, tt) f = true), + ((ZRange.type.base.option.is_bounded_by prime_bytes_bounds (type.app_curried (Interp rto_bytesv) f) = true + /\ (forall cast_outside_of_range, type.app_curried (expr.Interp (@ident.gen_interp cast_outside_of_range) rto_bytesv) f + = type.app_curried (t:=to_bytesT) (to_bytesmod machine_wordsize n) f)) + /\ (Positional.eval (weight 8 1) n_bytes (type.app_curried (t:=to_bytesT) (to_bytesmod machine_wordsize n) f)) = (Positional.eval (weight machine_wordsize 1) n (fst f) mod m))) + /\ (forall f + (Hf : type.andb_bool_for_each_lhs_of_arrow (t:=(base.type.list base.type.Z -> base.type.Z)%etype) (@ZRange.type.option.is_bounded_by) (Some bounds, tt) f = true), (Interp rnonzerov (fst f) = 0) <-> ((@eval machine_wordsize n (from_montgomery_mod machine_wordsize n m m' (fst f))) mod m = 0)). + + (** XXX TODO MOVE ME *) + Local Opaque valid addmod submod oppmod encodemod mulmod from_montgomery_mod nonzeromod. + Theorem Good : GoodT. + Proof. + pose proof use_curve_good; destruct_head'_and; destruct_head_hnf' ex. + split; [ | split ]. + { eapply MontgomeryStyleRing.Good; + lazymatch goal with + | [ H : ?P ?rop |- context[expr.Interp _ ?rop] ] + => intros; + let H1 := fresh in + let H2 := fresh in + unshelve edestruct H as [H1 H2]; [ .. | solve [ split; [ eapply H1 | eapply H2 ] ] ]; + solve [ exact tt | eassumption | reflexivity ] + | _ => idtac + end; + repeat first [ eassumption + | eapply mulmod_correct + | eapply addmod_correct + | eapply submod_correct + | eapply oppmod_correct + | eapply encodemod_correct + | eapply from_montgomery_mod_correct + | eapply nonzeromod_correct + | intros; apply conj + | omega ]. } + { cbv zeta; intros f Hf; split. + { apply Hto_bytesv; assumption. } + { cbn [type.for_each_lhs_of_arrow type_base type.andb_bool_for_each_lhs_of_arrow ZRange.type.option.is_bounded_by fst snd] in *. + rewrite Bool.andb_true_iff in *; split_and'. + apply to_bytesmod_correct; eauto; []. + split; cbv [small]. + admit. + admit. } } + { intros. + split; [ intro H'; eapply nonzeromod_correct; + [ .. | rewrite <- H'; symmetry; eapply Hrnonzerov ] + | etransitivity; [ apply Hrnonzerov | eapply nonzeromod_correct; [ .. | eassumption ] ] ]; + try eassumption. + admit. + admit. } + Admitted. + End make_ring. + + Section for_stringification. + Definition aggregate_infos {A B C} (ls : list (A * ErrorT B (C * ToString.C.ident_infos))) : ToString.C.ident_infos + := fold_right + ToString.C.ident_info_union + ToString.C.ident_info_empty + (List.map + (fun '(_, res) => match res with + | Success (_, infos) => infos + | Error _ => ToString.C.ident_info_empty + end) + ls). + + Definition extra_synthesis (function_name_prefix : string) (infos : ToString.C.ident_infos) + : list (string * Pipeline.ErrorT (list string)) * PositiveSet.t + := let ls_addcarryx := List.flat_map + (fun lg_split:positive => [sraddcarryx function_name_prefix lg_split; srsubborrowx function_name_prefix lg_split]) + (PositiveSet.elements (ToString.C.addcarryx_lg_splits infos)) in + let ls_mulx := List.map + (fun lg_split:positive => srmulx function_name_prefix lg_split) + (PositiveSet.elements (ToString.C.mulx_lg_splits infos)) in + let ls_cmov := List.map + (fun bitwidth:positive => srcmovznz function_name_prefix bitwidth) + (PositiveSet.elements (ToString.C.cmovznz_bitwidths infos)) in + let ls := ls_addcarryx ++ ls_mulx ++ ls_cmov in + let infos := aggregate_infos ls in + (List.map (fun '(name, res) => (name, (res <- res; Success (fst res))%error)) ls, + ToString.C.bitwidths_used infos). + + Local Open Scope string_scope. + Local Open Scope list_scope. + + Definition known_functions + := [("mul", srmul); + ("square", srsquare); + ("add", sradd); + ("sub", srsub); + ("opp", sropp); + ("from_montgomery", srfrom_montgomery); + ("nonzero", srnonzero); + ("selectznz", srselectznz); + ("to_bytes", srto_bytes); + ("from_bytes", srfrom_bytes)]. + + Definition synthesize_of_name (function_name_prefix : string) (name : string) + : string * ErrorT Pipeline.ErrorMessage (list string * ToString.C.ident_infos) + := fold_right + (fun v default + => match v with + | Some res => res + | None => default + end) + ((name, + Error + (Pipeline.Invalid_argument + ("Unrecognized request to synthesize """ ++ name ++ """; valid names are " ++ String.concat ", " (List.map (@fst _ _) known_functions))))) + (map + (fun '(expected_name, resf) => if string_beq name expected_name then Some (resf function_name_prefix) else None) + known_functions). + + (** Note: If you change the name or type signature of this + function, you will need to update the code in CLI.v *) + Definition Synthesize (function_name_prefix : string) (requests : list string) + : list (string * Pipeline.ErrorT (list string)) * PositiveSet.t (* types used *) + := let ls := match requests with + | nil => List.map (fun '(_, sr) => sr function_name_prefix) known_functions + | requests => List.map (synthesize_of_name function_name_prefix) requests + end in + let infos := aggregate_infos ls in + let '(extra_ls, extra_bit_widths) := extra_synthesis function_name_prefix infos in + (extra_ls ++ List.map (fun '(name, res) => (name, (res <- res; Success (fst res))%error)) ls, + PositiveSet.union extra_bit_widths (ToString.C.bitwidths_used infos)). + End for_stringification. + End rcarry_mul. +End WordByWordMontgomery. + Module SaturatedSolinas. Section MulMod. Context (s : Z) (c : list (Z * Z)) diff --git a/src/Experiments/NewPipeline/arith_rewrite_head.out b/src/Experiments/NewPipeline/arith_rewrite_head.out new file mode 100644 index 000000000..23b5205d2 --- /dev/null +++ b/src/Experiments/NewPipeline/arith_rewrite_head.out @@ -0,0 +1,16842 @@ +arith_rewrite_head = +match idc in (ident t) return (Compile.value' true t) with +| @ident.Literal t v => + match + t as t0 + return + (base.base_interp t0 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base t0))) + with + | base.type.unit => fun v0 : unit => UnderLets.Base ##(v0)%expr + | base.type.Z => fun v0 : Z => UnderLets.Base ##(v0)%expr + | base.type.bool => fun v0 : bool => UnderLets.Base ##(v0)%expr + | base.type.nat => fun v0 : nat => UnderLets.Base ##(v0)%expr + end v +| ident.Nat_succ => + fun x : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat +| ident.Nat_pred => + fun x : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat +| ident.Nat_max => + fun x x0 : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat +| ident.Nat_mul => + fun x x0 : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat +| ident.Nat_add => + fun x x0 : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat +| ident.Nat_sub => + fun x x0 : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat +| @ident.nil t => UnderLets.Base []%expr_pat +| @ident.cons t => + fun (x : defaults.expr (type.base t)) + (x0 : defaults.expr (type.base (base.type.list t))) => + UnderLets.Base (x :: x0)%expr_pat +| @ident.pair A B => + fun (x : defaults.expr (type.base A)) (x0 : defaults.expr (type.base B)) + => UnderLets.Base (x, x0)%expr_pat +| @ident.fst A B => + fun x : defaults.expr (type.base (A * B)%etype) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => + match + match idc with + | @ident.pair A0 B0 => Some (A0, B0) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + with + | type.base t3 => + fun _ : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base A)) => + match a with + | Some x' => UnderLets.Base (x' v) + | None => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end (Compile.reflect x0) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end (Compile.reflect x1) + | None => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + | _ => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end +| @ident.snd A B => + fun x : defaults.expr (type.base (A * B)%etype) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => + match + match idc with + | @ident.pair A0 B0 => Some (A0, B0) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + with + | type.base t2 => + fun _ : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t3 + B + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr (type.base B)) => + match a with + | Some x' => UnderLets.Base (x' v0) + | None => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end (Compile.reflect x0) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end (Compile.reflect x1) + | None => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + | _ => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end +| @ident.prod_rect A B T => + fun + (x : defaults.expr (type.base A) -> + defaults.expr (type.base B) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x0 : defaults.expr (type.base (A * B)%etype)) => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x1 : var (type.base A))(x2 : var (type.base B)), + UnderLets.to_expr (x ($x1) ($x2)))%expr @ x0)%expr_pat +| @ident.bool_rect T => + fun + (x + x0 : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base base.type.bool)) => + UnderLets.Base + (#(ident.bool_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat +| @ident.nat_rect P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base base.type.nat) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base base.type.nat)) => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat +| @ident.nat_rect_arrow P Q => + fun + (x : defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x0 : defaults.expr (type.base base.type.nat) -> + (defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x1 : defaults.expr (type.base base.type.nat)) + (x2 : defaults.expr (type.base P)) => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var + (type.base P -> + type.base Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) ($x5)))%expr @ x1 @ x2)%expr_pat +| @ident.list_rect A P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base + (#(ident.list_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var (type.base (base.type.list A))) + (x4 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat +| @ident.list_case A P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat +| @ident.List_length T => + fun x : defaults.expr (type.base (base.type.list T)) => + UnderLets.Base (#(ident.List_length)%expr @ x)%expr_pat +| ident.List_seq => + fun x x0 : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat +| @ident.List_firstn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base (#(ident.List_firstn)%expr @ x @ x0)%expr_pat +| @ident.List_skipn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base (#(ident.List_skipn)%expr @ x @ x0)%expr_pat +| @ident.List_repeat A => + fun (x : defaults.expr (type.base A)) + (x0 : defaults.expr (type.base base.type.nat)) => + UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat +| @ident.List_combine A B => + fun (x : defaults.expr (type.base (base.type.list A))) + (x0 : defaults.expr (type.base (base.type.list B))) => + UnderLets.Base (#(ident.List_combine)%expr @ x @ x0)%expr_pat +| @ident.List_map A B => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base + (#(ident.List_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat +| @ident.List_app A => + fun x x0 : defaults.expr (type.base (base.type.list A)) => + UnderLets.Base (x ++ x0)%expr +| @ident.List_rev A => + fun x : defaults.expr (type.base (base.type.list A)) => + UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat +| @ident.List_flat_map A B => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base + (#(ident.List_flat_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat +| @ident.List_partition A => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.bool))) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base + (#(ident.List_partition)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat +| @ident.List_fold_right A B => + fun + (x : defaults.expr (type.base B) -> + defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (x0 : defaults.expr (type.base A)) + (x1 : defaults.expr (type.base (base.type.list B))) => + UnderLets.Base + (#(ident.List_fold_right)%expr @ + (λ (x2 : var (type.base B))(x3 : var (type.base A)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat +| @ident.List_update_nth T => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base T) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base (base.type.list T))) => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat +| @ident.List_nth_default T => + fun (x : defaults.expr (type.base T)) + (x0 : defaults.expr (type.base (base.type.list T))) + (x1 : defaults.expr (type.base base.type.nat)) => + UnderLets.Base (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat +| ident.Z_add => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x0 + else + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base x + else UnderLets.Base (x + x0)%expr + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args >? 0 + then UnderLets.Base (##(args) - x' v)%expr + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr + (type.base t1)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a1 with + | Some x'1 => + UnderLets.Base + (x - x'1 v1)%expr + | None => + UnderLets.Base + (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false + s0 -> + Compile.value' true d0 + => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => + UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x + x0)%expr + | _ => UnderLets.Base (x + x0)%expr + end + | None => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else UnderLets.Base (x + x0)%expr + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x + x0)%expr + | _ => UnderLets.Base (x + x0)%expr + end + end + | ($_)%expr => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else UnderLets.Base (x + x0)%expr + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v0)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x + x0)%expr + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else UnderLets.Base (x + x0)%expr + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x + x0)%expr + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ f x1 => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args >? 0 + then + UnderLets.Base (##(args) - x' v)%expr + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a0 with + | Some x'0 => + if args + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr + (type.base t1)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a1 with + | Some x'1 => + UnderLets.Base + (x0 - x'1 v1)%expr + | None => + UnderLets.Base + (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' + false s0 -> + Compile.value' + true d0 => + UnderLets.Base + (x + x0)%expr + end (Compile.reflect x1) + | None => + UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | None => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + end + | ($_)%expr => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v0)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.Base + (- (x' v + x'0 v0))%expr + | None => + UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + end + | ($_)%expr => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v0)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + | _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + end + | None => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v0)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x0 - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x + x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else UnderLets.Base (x + x0)%expr + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x - x' v)%expr + | None => UnderLets.Base (x + x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x + x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x + x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x + x0)%expr + | _ => UnderLets.Base (x + x0)%expr + end + end +| ident.Z_mul => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x0 + else + if args0 =? 1 + then UnderLets.Base x + else + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args0 =? -1 + then UnderLets.Base (- x)%expr + else + if args + if args =? 1 + then UnderLets.Base x0 + else + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args + if args =? 1 + then UnderLets.Base x0 + else + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? -1 + then UnderLets.Base (x' v) + else + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.Base + (- (x * x'0 v0))%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args + if args =? 1 + then UnderLets.Base x0 + else + if args =? -1 + then UnderLets.Base (- x0)%expr + else + if args + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x + else + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x + else + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x + else + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ f x1 => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x + else + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? -1 + then UnderLets.Base (x' v) + else + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.Base + (- (x'0 v0 * x0))%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v0 * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.Base + (x' v * x'0 v0)%expr + | None => + UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + end + | ($_)%expr => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + end + | None => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v0 * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v * x0))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + if args =? 1 + then UnderLets.Base x + else + if args =? -1 + then UnderLets.Base (- x)%expr + else + if args UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x * x' v))%expr + | None => UnderLets.Base (x * x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + end +| ident.Z_pow => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat +| ident.Z_sub => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args =? 0 + then UnderLets.Base (- x0)%expr + else + if args0 =? 0 + then UnderLets.Base x + else + if args + if args =? 0 + then UnderLets.Base (- x0)%expr + else + if args + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 0 + then UnderLets.Base (x' v) + else + if args =? 0 + then UnderLets.Base (- x0)%expr + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args >? 0 + then + UnderLets.Base + (##(args) + x'0 v0)%expr + else + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr + (type.base t1)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a1 with + | Some x'1 => + if args + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v2 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t1 : base.type + => + defaults.expr + (type.base + t1)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + UnderLets.Base + (x + + x'2 v2)%expr + | None => + UnderLets.Base + (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' + false s0 -> + Compile.value' + true d0 + => + UnderLets.Base + (x - x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false + s0 -> + Compile.value' true d0 + => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => + UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => + if args =? 0 + then UnderLets.Base (- x0)%expr + else + if args + if args =? 0 + then UnderLets.Base (- x0)%expr + else + if args + if args =? 0 + then UnderLets.Base (- x0)%expr + else + if args + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + if args UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x - x0)%expr + | _ => UnderLets.Base (x - x0)%expr + end + end + | ($_)%expr => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + if args UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v0)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x - x0)%expr + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + if args UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x - x0)%expr + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ f x1 => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args >? 0 + then + UnderLets.Base + (- (x' v + ##((- args)%Z)))%expr + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a0 with + | Some x'0 => + if args + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t1 : base.type + => + defaults.expr + (type.base t1)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a1 with + | Some x'1 => + UnderLets.Base + (- + (x'1 v1 + x0))%expr + | None => + UnderLets.Base + (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' + false s0 -> + Compile.value' + true d0 => + UnderLets.Base + (x - x0)%expr + end (Compile.reflect x1) + | None => + UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => + if args + if args + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + end + | ($_)%expr => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v0 + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.Base + (x'0 v0 - x' v)%expr + | None => + UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + end + | ($_)%expr => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v0)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + | _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + end + | None => + match f with + | #(idc0)%expr_pat => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v0 + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match f with + | #(idc)%expr_pat => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (- (x' v + x0))%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base (x - x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base x + else + if args UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x + x' v)%expr + | None => UnderLets.Base (x - x0)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => UnderLets.Base (x - x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x - x0)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat + _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x - x0)%expr + | _ => UnderLets.Base (x - x0)%expr + end + end +| ident.Z_opp => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | ($_)%expr => + if negb (SubstVarLike.is_var_fst_snd_pair_opp x) + then + UnderLets.UnderLet x + (fun v0 : var (type.base base.type.Z) => + UnderLets.Base (- $v0)%expr) + else UnderLets.Base (- x)%expr + | @expr.App _ _ _ s _ #(idc)%expr_pat x0 => + match match idc with + | ident.Z_opp => Some tt + | _ => None + end with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => UnderLets.Base (x' v) + | None => UnderLets.Base (- x)%expr + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 => + UnderLets.Base (- x)%expr + end (Compile.reflect x0) + | None => + if negb (SubstVarLike.is_var_fst_snd_pair_opp x) + then + UnderLets.UnderLet x + (fun v : var (type.base base.type.Z) => + UnderLets.Base (- $v)%expr) + else UnderLets.Base (- x)%expr + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if negb (SubstVarLike.is_var_fst_snd_pair_opp x) + then + UnderLets.UnderLet x + (fun v0 : var (type.base base.type.Z) => + UnderLets.Base (- $v0)%expr) + else UnderLets.Base (- x)%expr + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) + _ => + if negb (SubstVarLike.is_var_fst_snd_pair_opp x) + then + UnderLets.UnderLet x + (fun v : var (type.base base.type.Z) => UnderLets.Base (- $v)%expr) + else UnderLets.Base (- x)%expr + | _ => + if negb (SubstVarLike.is_var_fst_snd_pair_opp x) + then + UnderLets.UnderLet x + (fun v : var (type.base base.type.Z) => UnderLets.Base (- $v)%expr) + else UnderLets.Base (- x)%expr + end +| ident.Z_div => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 1 + then UnderLets.Base x + else + if args =? 2 ^ Z.log2 args + then UnderLets.Base (x >> ##(Z.log2 args))%expr + else UnderLets.Base (x / x0)%expr + | None => UnderLets.Base (x / x0)%expr + end + | _ => UnderLets.Base (x / x0)%expr + end +| ident.Z_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 1 + then UnderLets.Base ##(0)%expr + else + if args =? 2 ^ Z.log2 args + then UnderLets.Base (x &' ##((args - 1)%Z))%expr + else UnderLets.Base (x mod x0)%expr + | None => UnderLets.Base (x mod x0)%expr + end + | _ => UnderLets.Base (x mod x0)%expr + end +| ident.Z_log2 => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_log2)%expr @ x)%expr_pat +| ident.Z_log2_up => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_log2_up)%expr @ x)%expr_pat +| ident.Z_eqb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat +| ident.Z_leb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat +| ident.Z_geb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat +| ident.Z_of_nat => + fun x : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat +| ident.Z_to_nat => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_to_nat)%expr @ x)%expr_pat +| ident.Z_shiftr => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x >> x0)%expr +| ident.Z_shiftl => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x << x0)%expr +| ident.Z_land => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else + match x with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base ##(0)%expr + else UnderLets.Base (x &' x0)%expr + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end + | None => + match x with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else UnderLets.Base (x &' x0)%expr + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end + end + | ($_)%expr => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else UnderLets.Base (x &' x0)%expr + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end + | _ => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base ##(0)%expr + else UnderLets.Base (x &' x0)%expr + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end + end +| ident.Z_lor => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x || x0)%expr +| ident.Z_bneg => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_bneg)%expr @ x)%expr_pat +| ident.Z_lnot_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat +| ident.Z_mul_split => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat + else + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + if args1 =? 0 + then + UnderLets.Base + (##(0)%expr, ##(0)%expr)%expr_pat + else + if args0 =? 1 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args1 =? 1 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base + ((- x1)%expr, ##(0)%expr)%expr_pat + else + if args1 =? -1 + then + UnderLets.Base + ((- x0)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args0 =? 1 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base + ((- x1)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args0 =? 1 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base ((- x1)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args0 =? 1 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base ((- x1)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then + UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat + else + if args0 =? 1 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base + ((- x0)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat + else + if args0 =? 1 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base ((- x0)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args0 =? 0 + then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat + else + if args0 =? 1 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + if args0 =? -1 + then + UnderLets.Base ((- x0)%expr, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | None => + UnderLets.UnderLet + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end +| ident.Z_add_get_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args0 + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args0 =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc0)%expr_pat x2 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ + x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ + s _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc0)%expr_pat x2 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ + x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ + s _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.Abs _ _ _ _ _ _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + match match idc with + | ident.Z_opp => Some tt + | _ => None + end with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x3 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ + x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ + _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | @expr.App _ _ _ s _ ($_)%expr _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x3 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc)%expr_pat x3 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun _ : Compile.value' false s2 -> Compile.value' true d2 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 + _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (_ @ _)%expr_pat _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc)%expr_pat x4 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun _ : Compile.value' false s2 -> Compile.value' true d2 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 + _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc)%expr_pat x4 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 + _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then UnderLets.Base (x0, ##(0)%expr)%expr_pat + else + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun + v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc)%expr_pat x3 => + match + match idc with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s0 -> d0)%ptype => + fun _ : Compile.value' false s0 -> Compile.value' true d0 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end +| ident.Z_add_with_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + if args =? 0 + then UnderLets.Base (x0 + x1)%expr + else + UnderLets.UnderLet + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base base.type.Z) => + UnderLets.Base ($v)%expr) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base base.type.Z) => + UnderLets.Base ($v)%expr) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v0 : var (type.base base.type.Z) => UnderLets.Base ($v0)%expr) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base base.type.Z) => UnderLets.Base ($v)%expr) + end +| ident.Z_add_with_get_carry => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + if + (args0 <=? 0) && (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + if + (args1 <=? 0) && (args <=? 0) && + (args1 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base + (x2, ##(0)%expr)%expr_pat + else + if (args =? 0) && (args1 =? 0) + then + UnderLets.Base + (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + if (args0 =? 0) && (args1 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ ##(args0)%expr @ + ##(args1)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + if (args0 =? 0) && (args1 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ ##(args0)%expr @ + ##(args1)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + if (args0 =? 0) && (args1 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ ##(args0)%expr @ ##(args1)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + if (args0 =? 0) && (args1 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ ##(args0)%expr @ ##(args1)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if + (args0 <=? 0) && (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base + (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ #(idc1)%expr_pat x3 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if + (args0 <=? 0) && + (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal + t5 v1 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v2 : Z + => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => None + end + with + | Some _ => + if + (args =? 0) && + (args0 =? 0) + then + UnderLets.Base + (x2, + ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v1)%expr, + # + (ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v1)%expr, + # + (ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (# + (ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (# + (ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + if + (args0 <=? 0) && (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base + (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s _ (_ @ _)%expr_pat _ | @expr.App _ _ + _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | _ => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x2, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | None => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base + (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc1)%expr_pat x3 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s _ (_ @ _)%expr_pat _ | @expr.App _ _ + _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc0)%expr_pat x3 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v1 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + (- + (#(ident.snd)%expr @ + $v2)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ + _ _ s _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.Abs _ _ _ _ _ _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x3 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ #(idc0)%expr_pat x3 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x2 @ + x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t4 v1 => + match + t4 as t5 + return + (base.base_interp + t5 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v2 : Z => + Some v2 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v1 + | _ => None + end + with + | Some args1 => + if + (args1 <=? 0) && + (args <=? 0) && + (args1 + args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal + t5 v1 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v2 : Z + => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => None + end + with + | Some _ => + if + (args =? 0) && + (args1 =? 0) + then + UnderLets.Base + (x1, + ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v1)%expr, + # + (ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v1)%expr, + # + (ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (# + (ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + (fun + v1 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (# + (ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ + #(idc1)%expr_pat x4 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a1 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a1 with + | Some x'1 => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ + x @ x1 @ + x'1 v1)%expr_pat + (fun + v2 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v2)%expr, + (- + (# + (ident.snd)%expr @ + $v2)%expr_pat)%expr)%expr_pat) + else + match + s0 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base + t5 => + fun + v2 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a2 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v3)%expr, + (- + (# + (ident.snd)%expr @ + $v3)%expr_pat)%expr)%expr_pat) + else + if + args =? 0 + then + UnderLets.UnderLet + (# + (ident.Z_add_get_carry)%expr @ + x @ x1 @ + x2)%expr_pat + (fun + v3 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v3)%expr, + # + (ident.snd)%expr @ + ($v3)%expr)%expr_pat) + else + UnderLets.UnderLet + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + (fun + v3 : + var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + ( + # + (ident.fst)%expr @ + ($v3)%expr, + # + (ident.snd)%expr @ + ($v3)%expr)%expr_pat) + | None => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr + _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ + (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s0 _ + (_ @ _)%expr_pat _ | @expr.App + _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) + _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end (Compile.reflect x3) + | None => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && + (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base + (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * + base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x4 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ + _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | @expr.App _ _ _ s _ ($_)%expr _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v1 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + (- + (#(ident.snd)%expr @ + $v2)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + #(ident.snd)%expr @ + ($v2)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (_ @ _)%expr_pat _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x5 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x5 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if + (args0 <=? 0) && (args <=? 0) && (args0 + args + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) + else + match x with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some _ => + if (args =? 0) && (args0 =? 0) + then + UnderLets.Base (x1, ##(0)%expr)%expr_pat + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ + x1 @ x' v)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + if args + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ + x @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ ($_)%expr _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ + _ _ s _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + if args =? 0 + then + UnderLets.UnderLet + (#(ident.Z_add_get_carry)%expr @ x @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | None => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ #(idc)%expr_pat x3 => + match match idc with + | ident.Z_opp => Some tt + | _ => None + end with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ + ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if args1 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x'0 v0 @ x1 @ + ##((- args1)%Z)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + else + if + (args0 =? 0) && + (args1 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + ##(args0)%expr @ + ##(args1)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + #(ident.snd)%expr @ + ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ + ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + end + | ($_)%expr => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | @expr.Abs _ _ _ _ _ _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x4 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ + x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ + ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + end + | None => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ + ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x4 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ + x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ + _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | ($_)%expr => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v1 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x1 @ x'0 v1)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + (- + (#(ident.snd)%expr @ $v2)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.Abs _ _ _ _ _ _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x4 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x2 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end (Compile.reflect x3) + | None => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ + ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x5 => + match + match idc1 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ + x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ + $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ + _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x5 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v1 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v0 @ x1 @ x'0 v1)%expr_pat + (fun + v2 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v2)%expr, + (- + (#(ident.snd)%expr @ $v2)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s2 _ #(idc0)%expr_pat x5 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s2 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s2 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s2 _ #(idc0)%expr_pat x6 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s2 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s2 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x6 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s1 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 <=? 0 + then + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ ##((- args0)%Z)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + (- + (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s0 -> d0)%ptype => + fun + _ : Compile.value' false s0 -> + Compile.value' true d0 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x5 => + match + match idc0 with + | ident.Z_opp => Some tt + | _ => None + end + with + | Some _ => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x' v @ x1 @ x'0 v0)%expr_pat + (fun + v1 : var + (type.base + (base.type.Z * + base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ + ($v1)%expr, + (- + (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | @expr.App _ _ _ s0 _ ($_)%expr _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | None => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end + | @expr.App _ _ _ s _ ($_)%expr _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t1 v0 => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v0 : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v1 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v1 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v1)%expr, + #(ident.snd)%expr @ ($v1)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + end + | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) + _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | _ => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match + t0 as t1 return (base.base_interp t1 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + if (args =? 0) && (args0 =? 0) + then + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + ##(args)%expr @ ##(args0)%expr)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, ##(0)%expr)%expr_pat) + else + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + (fun + v : var + (type.base + (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v0 : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun + v : var + (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | None => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) + => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + | ($_)%expr => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v0)%expr, + #(ident.snd)%expr @ ($v0)%expr)%expr_pat) + | _ => + UnderLets.UnderLet + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, + #(ident.snd)%expr @ ($v)%expr)%expr_pat) + end + end +| ident.Z_sub_get_borrow => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.UnderLet + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, #(ident.snd)%expr @ ($v)%expr)%expr_pat) +| ident.Z_sub_with_get_borrow => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + UnderLets.UnderLet + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base + (#(ident.fst)%expr @ ($v)%expr, #(ident.snd)%expr @ ($v)%expr)%expr_pat) +| ident.Z_zselect => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat +| ident.Z_add_modulo => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat +| ident.Z_rshi => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat +| ident.Z_cc_m => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat +| ident.Z_cast range => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat +| ident.Z_cast2 range => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => + match a with + | Some x' => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) t3 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a0 : option + (defaults.expr (type.base t3) -> + defaults.expr (type.base base.type.Z)) + => + match a0 with + | Some x'0 => + (fv <-- do_again + (base.type.Z * base.type.Z) + (#(ident.Z_cast (fst range))%expr @ + ($(x' v))%expr, + #(ident.Z_cast (snd range))%expr @ + ($(x'0 v0))%expr)%expr_pat; + UnderLets.Base (id (id fv)))%under_lets + | None => + UnderLets.Base + (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end (Compile.reflect x0) + | None => + UnderLets.Base + (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end (Compile.reflect x1) + | None => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + | _ => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end +| ident.fancy_add log2wordmax imm => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat +| ident.fancy_addc log2wordmax imm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat +| ident.fancy_sub log2wordmax imm => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat +| ident.fancy_subb log2wordmax imm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat +| ident.fancy_mulll log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat +| ident.fancy_mullh log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat +| ident.fancy_mulhl log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat +| ident.fancy_mulhh log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat +| ident.fancy_rshi log2wordmax x => + fun x0 : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat +| ident.fancy_selc => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat +| ident.fancy_selm log2wordmax => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat +| ident.fancy_sell => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat +| ident.fancy_addm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat +end + : Compile.value' true t diff --git a/src/Experiments/NewPipeline/fancy_rewrite_head.out b/src/Experiments/NewPipeline/fancy_rewrite_head.out index 2201473ab..b93038b7c 100644 --- a/src/Experiments/NewPipeline/fancy_rewrite_head.out +++ b/src/Experiments/NewPipeline/fancy_rewrite_head.out @@ -5,7 +5,8 @@ match idc in (ident t) return (Compile.value' true t) with t as t0 return (base.base_interp t0 -> - UnderLets.UnderLets base.type ident var (expr (type.base t0))) + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base t0))) with | base.type.unit => fun v0 : unit => UnderLets.Base ##(v0)%expr | base.type.Z => fun v0 : Z => UnderLets.Base ##(v0)%expr @@ -13,42 +14,44 @@ match idc in (ident t) return (Compile.value' true t) with | base.type.nat => fun v0 : nat => UnderLets.Base ##(v0)%expr end v | ident.Nat_succ => - fun x : expr (type.base base.type.nat) => + fun x : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat | ident.Nat_pred => - fun x : expr (type.base base.type.nat) => + fun x : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat | ident.Nat_max => - fun x x0 : expr (type.base base.type.nat) => + fun x x0 : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat | ident.Nat_mul => - fun x x0 : expr (type.base base.type.nat) => + fun x x0 : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat | ident.Nat_add => - fun x x0 : expr (type.base base.type.nat) => + fun x x0 : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat | ident.Nat_sub => - fun x x0 : expr (type.base base.type.nat) => + fun x x0 : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat | @ident.nil t => UnderLets.Base []%expr_pat | @ident.cons t => - fun (x : expr (type.base t)) (x0 : expr (type.base (base.type.list t))) - => UnderLets.Base (x :: x0)%expr_pat + fun (x : defaults.expr (type.base t)) + (x0 : defaults.expr (type.base (base.type.list t))) => + UnderLets.Base (x :: x0)%expr_pat | @ident.pair A B => - fun (x : expr (type.base A)) (x0 : expr (type.base B)) => - UnderLets.Base (x, x0)%expr_pat + fun (x : defaults.expr (type.base A)) (x0 : defaults.expr (type.base B)) + => UnderLets.Base (x, x0)%expr_pat | @ident.fst A B => - fun x : expr (type.base (A * B)%etype) => + fun x : defaults.expr (type.base (A * B)%etype) => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat | @ident.snd A B => - fun x : expr (type.base (A * B)%etype) => + fun x : defaults.expr (type.base (A * B)%etype) => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat | @ident.prod_rect A B T => fun - (x : expr (type.base A) -> - expr (type.base B) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x0 : expr (type.base (A * B)%etype)) => + (x : defaults.expr (type.base A) -> + defaults.expr (type.base B) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x0 : defaults.expr (type.base (A * B)%etype)) => UnderLets.Base (#(ident.prod_rect)%expr @ (λ (x1 : var (type.base A))(x2 : var (type.base B)), @@ -56,9 +59,10 @@ match idc in (ident t) return (Compile.value' true t) with | @ident.bool_rect T => fun (x - x0 : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x1 : expr (type.base base.type.bool)) => + x0 : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base base.type.bool)) => UnderLets.Base (#(ident.bool_rect)%expr @ (λ x2 : var (type.base base.type.unit), @@ -67,27 +71,57 @@ match idc in (ident t) return (Compile.value' true t) with UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat | @ident.nat_rect P => fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base base.type.nat) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base base.type.nat)) => + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base base.type.nat) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base base.type.nat)) => UnderLets.Base (#(ident.nat_rect)%expr @ (λ x2 : var (type.base base.type.unit), UnderLets.to_expr (x ($x2)))%expr @ (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat +| @ident.nat_rect_arrow P Q => + fun + (x : defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x0 : defaults.expr (type.base base.type.nat) -> + (defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x1 : defaults.expr (type.base base.type.nat)) + (x2 : defaults.expr (type.base P)) => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var + (type.base P -> + type.base Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) ($x5)))%expr @ x1 @ x2)%expr_pat | @ident.list_rect A P => fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base A) -> - expr (type.base (base.type.list A)) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base (base.type.list A))) => + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => UnderLets.Base (#(ident.list_rect)%expr @ (λ x2 : var (type.base base.type.unit), @@ -97,12 +131,14 @@ match idc in (ident t) return (Compile.value' true t) with UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat | @ident.list_case A P => fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base A) -> - expr (type.base (base.type.list A)) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base (base.type.list A))) => + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => UnderLets.Base (#(ident.list_case)%expr @ (λ x2 : var (type.base base.type.unit), @@ -110,80 +146,95 @@ match idc in (ident t) return (Compile.value' true t) with (λ (x2 : var (type.base A))(x3 : var (type.base (base.type.list A))), UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat | @ident.List_length T => - fun x : expr (type.base (base.type.list T)) => + fun x : defaults.expr (type.base (base.type.list T)) => UnderLets.Base (#(ident.List_length)%expr @ x)%expr_pat | ident.List_seq => - fun x x0 : expr (type.base base.type.nat) => + fun x x0 : defaults.expr (type.base base.type.nat) => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat +| @ident.List_firstn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base (#(ident.List_firstn)%expr @ x @ x0)%expr_pat +| @ident.List_skipn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + UnderLets.Base (#(ident.List_skipn)%expr @ x @ x0)%expr_pat | @ident.List_repeat A => - fun (x : expr (type.base A)) (x0 : expr (type.base base.type.nat)) => + fun (x : defaults.expr (type.base A)) + (x0 : defaults.expr (type.base base.type.nat)) => UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat | @ident.List_combine A B => - fun (x : expr (type.base (base.type.list A))) - (x0 : expr (type.base (base.type.list B))) => + fun (x : defaults.expr (type.base (base.type.list A))) + (x0 : defaults.expr (type.base (base.type.list B))) => UnderLets.Base (#(ident.List_combine)%expr @ x @ x0)%expr_pat | @ident.List_map A B => fun - (x : expr (type.base A) -> - UnderLets.UnderLets base.type ident var (expr (type.base B))) - (x0 : expr (type.base (base.type.list A))) => + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + (x0 : defaults.expr (type.base (base.type.list A))) => UnderLets.Base (#(ident.List_map)%expr @ (λ x1 : var (type.base A), UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat | @ident.List_app A => - fun x x0 : expr (type.base (base.type.list A)) => + fun x x0 : defaults.expr (type.base (base.type.list A)) => UnderLets.Base (x ++ x0)%expr | @ident.List_rev A => - fun x : expr (type.base (base.type.list A)) => + fun x : defaults.expr (type.base (base.type.list A)) => UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat | @ident.List_flat_map A B => fun - (x : expr (type.base A) -> + (x : defaults.expr (type.base A) -> UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (x0 : expr (type.base (base.type.list A))) => + (defaults.expr (type.base (base.type.list B)))) + (x0 : defaults.expr (type.base (base.type.list A))) => UnderLets.Base (#(ident.List_flat_map)%expr @ (λ x1 : var (type.base A), UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat | @ident.List_partition A => fun - (x : expr (type.base A) -> + (x : defaults.expr (type.base A) -> UnderLets.UnderLets base.type ident var - (expr (type.base base.type.bool))) - (x0 : expr (type.base (base.type.list A))) => + (defaults.expr (type.base base.type.bool))) + (x0 : defaults.expr (type.base (base.type.list A))) => UnderLets.Base (#(ident.List_partition)%expr @ (λ x1 : var (type.base A), UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat | @ident.List_fold_right A B => fun - (x : expr (type.base B) -> - expr (type.base A) -> - UnderLets.UnderLets base.type ident var (expr (type.base A))) - (x0 : expr (type.base A)) (x1 : expr (type.base (base.type.list B))) => + (x : defaults.expr (type.base B) -> + defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (x0 : defaults.expr (type.base A)) + (x1 : defaults.expr (type.base (base.type.list B))) => UnderLets.Base (#(ident.List_fold_right)%expr @ (λ (x2 : var (type.base B))(x3 : var (type.base A)), UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat | @ident.List_update_nth T => - fun (x : expr (type.base base.type.nat)) - (x0 : expr (type.base T) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x1 : expr (type.base (base.type.list T))) => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base T) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base (base.type.list T))) => UnderLets.Base (#(ident.List_update_nth)%expr @ x @ (λ x2 : var (type.base T), UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat | @ident.List_nth_default T => - fun (x : expr (type.base T)) (x0 : expr (type.base (base.type.list T))) - (x1 : expr (type.base base.type.nat)) => + fun (x : defaults.expr (type.base T)) + (x0 : defaults.expr (type.base (base.type.list T))) + (x1 : defaults.expr (type.base base.type.nat)) => UnderLets.Base (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat | ident.Z_add => - fun x x0 : expr (type.base base.type.Z) => UnderLets.Base (x + x0)%expr + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x + x0)%expr | ident.Z_mul => - fun x x0 : expr (type.base base.type.Z) => + fun x x0 : defaults.expr (type.base base.type.Z) => match x with | #(idc)%expr_pat => match @@ -200,851 +251,5664 @@ match idc in (ident t) return (Compile.value' true t) with with | Some args => match x0 with - | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc0)%expr_pat x2) + x1 => match match idc0 with - | ident.Z_land mask => Some mask + | ident.Z_land => Some tt | _ => None end with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 =? 2 ^ (2 * Z.log2_up args0 / 2) - 1 - then + | Some _ => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 + then + match + invert_low (2 * Z.log2_up args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args1))%expr @ + (##(x3)%expr, x' v))%expr_pat + | None => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp + t5 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v1 : Z => + Some v1 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_low + (2 * + Z.log2_up + args2) + args + with + | Some x3 => + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'1 v1))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + end + else + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'1 v1))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + | None => + match + s0 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + | ($_)%expr => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v1))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | @expr.Abs _ _ _ _ _ _ => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | (_ @ _)%expr_pat => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + end + else + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_low + (2 * + Z.log2_up + args2) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'1 v1))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + end + else + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args2))%expr @ + (## + (x3)%expr, + x'1 v1))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args1 =? + 2 + ^ + (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some + x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'2 v2))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + | None => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + | ($_)%expr => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x3)%expr, + x'0 v1))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | @expr.Abs _ _ _ _ _ _ => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | (_ @ _)%expr_pat => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + end + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x2 with + | #(idc2)%expr_pat => match - invert_low (2 * Z.log2_up args0) args + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end with - | Some x2 => - UnderLets.Base - (#(ident.fancy_mulll - (2 * Z.log2_up args0))%expr @ - (##(x2)%expr, x' v))%expr_pat - | None => + | Some args1 => match s as t3 return (Compile.value' false t3 -> UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) + var + (defaults.expr + (type.base base.type.Z))) with | type.base t3 => - fun v0 : expr (type.base t3) => + fun v : defaults.expr (type.base t3) + => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 base.type.Z (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) + (defaults.expr + (type.base base.type.Z))) (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => - match a0 with - | Some x'0 => + match a with + | Some x' => if - args0 =? - 2 ^ (2 * Z.log2_up args0 / 2) - + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 then match - invert_high - (2 * Z.log2_up args0) + invert_low + (2 * Z.log2_up args1) args with - | Some x2 => + | Some x3 => UnderLets.Base - (#(ident.fancy_mulhl + (#(ident.fancy_mulll (2 * - Z.log2_up args0))%expr @ - (##(x2)%expr, x'0 v0))%expr_pat + Z.log2_up args1))%expr @ + (##(x3)%expr, x' v))%expr_pat | None => - UnderLets.Base - (x * x0)%expr + match + s as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) end else - UnderLets.Base (x * x0)%expr + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) | None => UnderLets.Base (x * x0)%expr end) - | (s0 -> d0)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base (x * x0)%expr end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr end - else + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => match s as t3 return (Compile.value' false t3 -> UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) + (defaults.expr (type.base base.type.Z))) with | type.base t3 => - fun v0 : expr (type.base t3) => + fun v0 : defaults.expr (type.base t3) => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z (UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) + var + (defaults.expr + (type.base base.type.Z))) (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => if - args0 =? - 2 ^ (2 * Z.log2_up args0 / 2) - 1 + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 then match - invert_high - (2 * Z.log2_up args0) args + invert_low + (2 * Z.log2_up args1) args with - | Some x2 => + | Some x3 => UnderLets.Base - (#(ident.fancy_mulhl - (2 * Z.log2_up args0))%expr @ - (##(x2)%expr, x'0 v0))%expr_pat + (#(ident.fancy_mulll + (2 * Z.log2_up args1))%expr @ + (##(x3)%expr, x' v0))%expr_pat | None => - UnderLets.Base (x * x0)%expr + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v1))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) end - else UnderLets.Base (x * x0)%expr + else + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x3)%expr, + x'0 v1))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) | None => UnderLets.Base (x * x0)%expr end) - | (s0 -> d0)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base (x * x0)%expr end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match invert_low (2 * args0) args with - | Some x2 => - UnderLets.Base - (#(ident.fancy_mullh (2 * args0))%expr @ - (##(x2)%expr, x' v))%expr_pat - | None => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - match - invert_high (2 * args0) - args - with - | Some x2 => - UnderLets.Base - (#(ident.fancy_mulhh - (2 * args0))%expr @ - (##(x2)%expr, - x'0 v0))%expr_pat - | None => - UnderLets.Base - (x * x0)%expr - end - | None => - UnderLets.Base - (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - end - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_land mask => Some mask - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? 2 ^ (2 * Z.log2_up args / 2) - 1 - then + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => match - invert_low (2 * Z.log2_up args) args0 + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) with - | Some y => - UnderLets.Base - (#(ident.fancy_mulll - (2 * Z.log2_up args))%expr @ - (x' v, ##(y)%expr))%expr_pat - | None => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if - args =? - 2 ^ (2 * Z.log2_up args / 2) - - 1 - then - match - invert_high - (2 * Z.log2_up args) - args0 - with - | Some y => - UnderLets.Base - (#(ident.fancy_mullh - (2 * - Z.log2_up args))%expr @ - (x'0 v0, ##(y)%expr))%expr_pat - | None => + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args1) args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args1))%expr @ + (##(x3)%expr, x' v))%expr_pat + | None => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => UnderLets.Base (x * x0)%expr - end - else + end (Compile.reflect x1) + end + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => UnderLets.Base (x * x0)%expr - | None => - UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - end - else + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | (_ @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => match - s as t3 + s as t2 return - (Compile.value' false t3 -> + (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) + (defaults.expr (type.base base.type.Z))) with - | type.base t3 => - fun v0 : expr (type.base t3) => + | type.base t2 => + fun v : defaults.expr (type.base t2) => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z (UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) + var + (defaults.expr + (type.base base.type.Z))) (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => if - args =? - 2 ^ (2 * Z.log2_up args / 2) - 1 + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 then match - invert_high - (2 * Z.log2_up args) args0 + invert_low + (2 * Z.log2_up args1) args with - | Some y => + | Some x4 => UnderLets.Base - (#(ident.fancy_mullh - (2 * Z.log2_up args))%expr @ - (x'0 v0, ##(y)%expr))%expr_pat + (#(ident.fancy_mulll + (2 * Z.log2_up args1))%expr @ + (##(x4)%expr, x' v))%expr_pat | None => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + end + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args1 =? + 2 ^ (2 * Z.log2_up args1 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args1) args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args1))%expr @ + (##(x4)%expr, x' v))%expr_pat + | None => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up + args1 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (## + (x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) end - else UnderLets.Base (x * x0)%expr + else + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args1 =? + 2 + ^ (2 * + Z.log2_up args1 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args1) + args + with + | Some x4 => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + Z.log2_up + args1))%expr @ + (##(x4)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) | None => UnderLets.Base (x * x0)%expr end) - | (s0 -> d0)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base (x * x0)%expr end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_land mask => Some mask - | _ => None - end - with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if - (args =? - 2 ^ (2 * Z.log2_up args / 2) - 1) && - (args0 =? - 2 ^ (2 * Z.log2_up args / 2) - 1) - then - UnderLets.Base - (#(ident.fancy_mulll - (2 * Z.log2_up args))%expr @ - (x' v, x'0 v0))%expr_pat - else UnderLets.Base (x * x0)%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end | None => match match idc0 with - | ident.Z_shiftr offset => Some offset + | ident.Z_shiftr => Some tt | _ => None end with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if - args =? - 2 ^ (2 * args0 / 2) - 1 - then + | Some _ => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + match + invert_low (2 * args1) args + with + | Some x3 => UnderLets.Base (#(ident.fancy_mullh - (2 * args0))%expr @ - (x' v, x'0 v0))%expr_pat - else - UnderLets.Base (x * x0)%expr - | None => - UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) + (2 * args1))%expr @ + (##(x3)%expr, x' v))%expr_pat + | None => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + match + invert_high + (2 * args1) + args + with + | Some x3 => + UnderLets.Base + (#(ident.fancy_mulhh + (2 * + args1))%expr @ + (##(x3)%expr, + x'0 v0))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false + s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end | None => UnderLets.Base (x * x0)%expr end end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | + @expr.App _ _ _ s _ + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s _ + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ + ($_)%expr _ | @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | + @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr | _ => UnderLets.Base (x * x0)%expr end - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x2) x1 => + match match idc with + | ident.Z_land => Some tt | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => + end with + | Some _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match invert_low (2 * args) args0 with - | Some y => - UnderLets.Base - (#(ident.fancy_mulhl (2 * args))%expr @ - (x' v, ##(y)%expr))%expr_pat - | None => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - match - invert_high (2 * args) - args0 - with - | Some y => - UnderLets.Base - (#(ident.fancy_mulhh - (2 * args))%expr @ - (x'0 v0, ##(y)%expr))%expr_pat - | None => - UnderLets.Base - (x * x0)%expr + | Some args1 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - 1 + then + match + invert_low (2 * Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match x1 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp + t5 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v1 : Z => + Some v1 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None end - | None => - UnderLets.Base - (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - end - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_land mask => Some mask - | _ => None - end - with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if - args0 =? - 2 ^ (2 * args / 2) - 1 - then - UnderLets.Base - (#(ident.fancy_mulhl - (2 * args))%expr @ - (x' v, x'0 v0))%expr_pat - else - UnderLets.Base (x * x0)%expr - | None => - UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args0 => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_low + (2 * + Z.log2_up + args2) + args1 + with + | Some y => + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args2))%expr @ + ( + x'0 v0, + ## + (y)%expr))%expr_pat + | None => + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + ## + (y)%expr))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + end + else + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + ## + (y)%expr))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + match + s as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + end + | ($_)%expr => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - if args =? args0 - then - UnderLets.Base - (#(ident.fancy_mulhh - (2 * args))%expr @ - (x' v, x'0 v0))%expr_pat - else - UnderLets.Base - (x * x0)%expr - | None => - UnderLets.Base - (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v1, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + | _ => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + end + end + else + match x1 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_low + (2 * + Z.log2_up + args2) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args2))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + ## + (y)%expr))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + end + else + match + s as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + if + args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + ## + (y)%expr))%expr_pat + | None => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + end + else + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v2 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args2 =? + 2 + ^ + (2 * + Z.log2_up + args2 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args2) + args1 + with + | Some + y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args2))%expr @ + ( + x'2 v2, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> + d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : + Compile.value' + false s1 -> + Compile.value' + true d1 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x1) + end + | ($_)%expr => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v1, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | @expr.LetIn _ _ _ _ _ _ _ => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | _ => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + end | None => UnderLets.Base (x * x0)%expr end) | (s1 -> d1)%ptype => @@ -1055,4847 +5919,28966 @@ match idc in (ident t) return (Compile.value' true t) with end (Compile.reflect x1) | None => UnderLets.Base (x * x0)%expr end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ #(idc1)%expr_pat x4) x3 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + match + s1 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, x'0 v0))%expr_pat + else + match x1 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s1 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + match + x3 + with + | # + (idc4)%expr_pat => + match + match + idc4 + with + | @ident.Literal + t9 v3 => + match + t9 as t10 + return + (base.base_interp + t10 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v4 : Z => + Some v4 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v3 + | _ => + None + end + with + | Some + args4 => + match + s as t9 + return + (Compile.value' + false t9 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t9 => + fun + v3 : + defaults.expr + (type.base + t9) => + base.try_make_transport_cps + (fun + t10 : base.type + => + defaults.expr + (type.base + t10)) t9 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a3 : + option + (defaults.expr + (type.base + t9) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a3 + with + | Some + x'3 => + match + s2 as t10 + return + (Compile.value' + false t10 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t10 => + fun + v4 : + defaults.expr + (type.base + t10) => + base.try_make_transport_cps + (fun + t11 : base.type + => + defaults.expr + (type.base + t11)) t10 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a4 : + option + (defaults.expr + (type.base + t10) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a4 + with + | Some + x'4 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args4 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'3 v3, + x'4 v4))%expr_pat + else + match + s0 as t11 + return + (Compile.value' + false t11 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t11 => + fun + v5 : + defaults.expr + (type.base + t11) => + base.try_make_transport_cps + (fun + t12 : base.type + => + defaults.expr + (type.base + t12)) t11 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a5 : + option + (defaults.expr + (type.base + t11) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a5 + with + | Some + x'5 => + match + s2 as t12 + return + (Compile.value' + false t12 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t12 => + fun + v6 : + defaults.expr + (type.base + t12) => + base.try_make_transport_cps + (fun + t13 : base.type + => + defaults.expr + (type.base + t13)) t12 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a6 : + option + (defaults.expr + (type.base + t12) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a6 + with + | Some + x'6 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args4 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'5 v5, + x'6 v6))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x3) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + match + x3 + with + | # + (idc4)%expr_pat => + match + match + idc4 + with + | @ident.Literal + t7 v1 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v1 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v2 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t7 v2 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v3 : Z => + Some v3 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v2 + | _ => + None + end + with + | Some + args3 => + match + s as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v3 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v2, + x'2 v3))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | @expr.LetIn _ _ + _ _ _ _ _ => + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | _ => + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x1) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false + s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x3) + | None => + UnderLets.Base (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + match + x1 + with + | # + (idc4)%expr_pat => + match + match + idc4 + with + | @ident.Literal + t7 v1 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v1 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v2 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' false + t5 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base t5) + => + base.try_make_transport_cps + (fun t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v0, + x'0 v1))%expr_pat + else + match x1 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t7 v2 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v3 : Z => + Some v3 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v2 + | _ => + None + end + with + | Some + args3 => + match + s0 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v3 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'1 v2, + x'2 v3))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x1 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x1 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args3 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args3))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * args2 / + 2) - 1 + then + UnderLets.Base + (#(ident.fancy_mullh + (2 * + args2))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x1 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args3 =? + 2 + ^ + (2 * + args2 / 2) - + 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x1) + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s1 _ (@expr.App _ _ _ s2 _ ($_)%expr _) + _ | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (_ @ _)%expr_pat _) _ | @expr.App + _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _) + _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s1 _ #(_)%expr_pat _ | @expr.App _ _ _ + s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - | None => UnderLets.Base (x * x0)%expr - end - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end -| ident.Z_pow => - fun x x0 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat -| ident.Z_sub => - fun x x0 : expr (type.base base.type.Z) => UnderLets.Base (x - x0)%expr -| ident.Z_opp => - fun x : expr (type.base base.type.Z) => UnderLets.Base (- x)%expr -| ident.Z_div => - fun x x0 : expr (type.base base.type.Z) => UnderLets.Base (x / x0)%expr -| ident.Z_modulo => - fun x x0 : expr (type.base base.type.Z) => UnderLets.Base (x mod x0)%expr -| ident.Z_eqb => - fun x x0 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat -| ident.Z_leb => - fun x x0 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat -| ident.Z_of_nat => - fun x : expr (type.base base.type.nat) => - UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat -| ident.Z_shiftr offset => - fun x : expr (type.base base.type.Z) => UnderLets.Base (x >> offset)%expr -| ident.Z_shiftl offset => - fun x : expr (type.base base.type.Z) => UnderLets.Base (x << offset)%expr -| ident.Z_land mask => - fun x : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_land mask)%expr @ x)%expr_pat -| ident.Z_mul_split => - fun x x0 x1 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat -| ident.Z_mul_split_concrete s => - fun x x0 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_mul_split_concrete s)%expr @ x @ x0)%expr_pat -| ident.Z_add_get_carry => - fun x x0 x1 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat -| ident.Z_add_get_carry_concrete s => - fun x x0 : expr (type.base base.type.Z) => - match x0 with - | #(_)%expr_pat => - match x with - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | ($_)%expr => - match x with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match x with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x, x' v))%expr_pat - else - match x with - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args0 => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) - args0)%expr @ (x0, x'0 v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) - 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end (Compile.reflect x2) - | None => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc2)%expr_pat => match - match idc0 with - | ident.Z_shiftr offset => Some offset + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with - | Some args0 => + | Some args1 => match - s1 as t3 + s0 as t3 return (Compile.value' false t3 -> UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) + (defaults.expr + (type.base base.type.Z))) with | type.base t3 => - fun v0 : expr (type.base t3) => + fun v : defaults.expr (type.base t3) + => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 base.type.Z (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) + (defaults.expr + (type.base base.type.Z))) (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - + 1 then - UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) (- args0))%expr @ - (x0, x'0 v0))%expr_pat + match + invert_low + (2 * Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match + s0 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + ( + x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' + true d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat + UnderLets.Base (x * x0)%expr end) - | (s2 -> d1)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s2 -> + _ : Compile.value' false s1 -> Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat + UnderLets.Base (x * x0)%expr end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat + | None => UnderLets.Base (x * x0)%expr end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ - s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 - _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match x with - | #(_)%expr_pat => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | @expr.Abs _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x2 => + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ #(idc2)%expr_pat x4) + x3 => + match + match idc2 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s1 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + match + x3 + with + | # + (idc4)%expr_pat => + match + match + idc4 + with + | @ident.Literal + t7 v1 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v1 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v2 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x3) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x3 with + | #(idc4)%expr_pat => + match + match idc4 with + | @ident.Literal t5 v => + match + t5 as t6 + return + (base.base_interp + t6 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v0 : Z => + Some v0 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t5 + return + (Compile.value' false + t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v : defaults.expr + (type.base t5) + => + base.try_make_transport_cps + (fun t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v0 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 v0 => + match + t5 as t6 + return + (base.base_interp t6 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t5 + return + (Compile.value' false t5 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base t5) + => + base.try_make_transport_cps + (fun t6 : base.type => + defaults.expr + (type.base t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' true + d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc2 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args0 =? + 2 + ^ + (2 * + args2 / 2) - + 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ ($_)%expr _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) + _) _ | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s1 _ #(_)%expr_pat _ | + @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ + _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App + _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x1 with + | #(idc0)%expr_pat => match match idc0 with - | ident.Z_shiftl offset => Some offset + | @ident.Literal t2 v0 => + match + t2 as t3 return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 | _ => None end with | Some args0 => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args0)%expr @ - (x0, x' v))%expr_pat - else + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args0) args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args0))%expr @ + (x' v0, ##(y)%expr))%expr_pat + | None => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v1, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + else + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v1 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v1, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ #(idc1)%expr_pat x4) x3 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s1 as t5 + return + (Compile.value' false + t5 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base t5) + => + base.try_make_transport_cps + (fun t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v0, + x'0 v1))%expr_pat + else + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t7 v2 => + match + t7 as t8 + return + (base.base_interp + t8 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v3 : Z => + Some v3 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v2 + | _ => + None + end + with + | Some + args3 => + match + s0 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t8 + return + (Compile.value' + false t8 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t8 => + fun + v3 : + defaults.expr + (type.base + t8) => + base.try_make_transport_cps + (fun + t9 : base.type + => + defaults.expr + (type.base + t9)) t8 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t8) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v2, + x'2 v3))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x3) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 v0 => + match + t5 as t6 + return + (base.base_interp t6 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t5 + return + (Compile.value' false t5 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base t5) + => + base.try_make_transport_cps + (fun t6 : base.type => + defaults.expr + (type.base t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t5 v1 => + match + t5 as t6 + return + (base.base_interp t6 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v2 : Z => Some v2 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v1 + | _ => None + end + with + | Some args2 => + match + s0 as t5 + return + (Compile.value' false t5 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base t5) => + base.try_make_transport_cps + (fun t6 : base.type => + defaults.expr + (type.base t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t6 => + fun + v2 : defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base t7)) + t6 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v1, + x'0 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ + (2 * args2 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ ($_)%expr _) _ | @expr.App _ + _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _) + _ | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s1 _ #(_)%expr_pat _ | @expr.App _ + _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.Abs _ _ _ _ _ _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args0) args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ #(idc1)%expr_pat x4) x3 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s3 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x3) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' true + d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s5 -> d5)%ptype => + fun + _ : Compile.value' + false s5 -> + Compile.value' + true d5 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s5 -> d5)%ptype => + fun + _ : Compile.value' false s5 -> + Compile.value' true d5 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ + (2 * args2 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ ($_)%expr _) _ | @expr.App _ + _ _ s2 _ + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _) + _ | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s2 _ #(_)%expr_pat _ | @expr.App _ + _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | (_ @ _)%expr_pat => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args0) args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' + false s2 -> + Compile.value' true + d2 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ #(idc1)%expr_pat x5) x4 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x4 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s3 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> + d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : + Compile.value' + false s4 -> + Compile.value' + true d4 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' true + d4 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s5 -> d5)%ptype => + fun + _ : Compile.value' + false s5 -> + Compile.value' + true d5 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s5 -> d5)%ptype => + fun + _ : Compile.value' false s5 -> + Compile.value' true d5 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s3 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ + (2 * args2 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ ($_)%expr _) _ | @expr.App _ + _ _ s2 _ + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _) + _ | @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s2 _ + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s2 _ #(_)%expr_pat _ | @expr.App _ + _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if + args0 =? + 2 ^ (2 * Z.log2_up args0 / 2) - 1 + then + match + invert_low + (2 * Z.log2_up args0) args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulll + (2 * Z.log2_up args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1 + then + match + invert_high + (2 * + Z.log2_up + args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ## + (y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' + false s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + else + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ (2 * + Z.log2_up args0 / + 2) - 1 + then + match + invert_high + (2 * + Z.log2_up args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mullh + (2 * + Z.log2_up + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ #(idc1)%expr_pat x5) x4 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s1 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (#(ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x4 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args3 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + (args0 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) && + (args2 =? + 2 + ^ + (2 * + Z.log2_up + args0 / 2) - + 1) + then + UnderLets.Base + (# + (ident.fancy_mulll + (2 * + Z.log2_up + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + 2 + ^ + (2 * args2 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mullh + (2 * + args2))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x5) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ ($_)%expr _) _ | @expr.App _ + _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _) + _ | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s1 _ #(_)%expr_pat _ | @expr.App _ + _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + match + invert_low (2 * args0) args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulhl + (2 * args0))%expr @ + (x' v, ##(y)%expr))%expr_pat + | None => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + match + invert_high + (2 * args0) + args1 + with + | Some y => + UnderLets.Base + (#(ident.fancy_mulhh + (2 * + args0))%expr @ + (x'0 v0, + ##(y)%expr))%expr_pat + | None => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false + s1 -> + Compile.value' true + d1 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + end + | None => UnderLets.Base (x * x0)%expr + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => UnderLets.Base (x * x0)%expr + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ #(idc1)%expr_pat x4) x3 => + match + match idc1 with + | ident.Z_land => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + match + s1 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ (2 * args0 / + 2) - 1 + then + UnderLets.Base + (#(ident.fancy_mulhl + (2 * + args0))%expr @ + (x' v, + x'0 v0))%expr_pat + else + match x3 with + | #(idc3)%expr_pat => + match + match + idc3 + with + | @ident.Literal + t6 v1 => + match + t6 as t7 + return + (base.base_interp + t7 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v2 : Z => + Some v2 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v1 + | _ => + None + end + with + | Some + args3 => + match + s0 as t6 + return + (Compile.value' + false t6 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t6 => + fun + v1 : + defaults.expr + (type.base + t6) => + base.try_make_transport_cps + (fun + t7 : base.type + => + defaults.expr + (type.base + t7)) t6 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a1 : + option + (defaults.expr + (type.base + t6) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a1 + with + | Some + x'1 => + match + s2 as t7 + return + (Compile.value' + false t7 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base + t7 => + fun + v2 : + defaults.expr + (type.base + t7) => + base.try_make_transport_cps + (fun + t8 : base.type + => + defaults.expr + (type.base + t8)) t7 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a2 : + option + (defaults.expr + (type.base + t7) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a2 + with + | Some + x'2 => + if + args3 =? + 2 + ^ + (2 * + args0 / 2) - + 1 + then + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + args0))%expr @ + ( + x'1 v1, + x'2 v2))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> + d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x2) + | None => + UnderLets.Base + (x * x0)%expr + end + | _ => + UnderLets.Base + (x * x0)%expr + end + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x3) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args2 =? + 2 + ^ + (2 * + args0 / 2) - + 1 + then + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect + x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | ($_)%expr => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t5 => + fun + v1 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base t6)) + t5 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ + (2 * args0 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + args0))%expr @ + ( + x' v0, + x'0 v1))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ + (2 * args0 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args2 =? + 2 + ^ + (2 * args0 / + 2) - 1 + then + UnderLets.Base + (# + (ident.fancy_mulhl + (2 * + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' + true d4 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + match + s2 as t4 + return + (Compile.value' + false t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + base.type.Z))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base + t4) => + base.try_make_transport_cps + (fun + t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : + option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args0 =? + args2 + then + UnderLets.Base + (# + (ident.fancy_mulhh + (2 * + args0))%expr @ + ( + x' v, + x'0 v0))%expr_pat + else + UnderLets.Base + (x * x0)%expr + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (x * x0)%expr + end + (Compile.reflect x4) + | None => + UnderLets.Base + (x * x0)%expr + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base (x * x0)%expr + end (Compile.reflect x2) + | None => + UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ ($_)%expr _) _ | @expr.App _ + _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _) + _ | @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s1 _ + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _) _ => UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s1 _ #(_)%expr_pat _ | @expr.App _ + _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ + (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (x * x0)%expr + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x * x0)%expr + | _ => UnderLets.Base (x * x0)%expr + end +| ident.Z_pow => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat +| ident.Z_sub => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x - x0)%expr +| ident.Z_opp => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (- x)%expr +| ident.Z_div => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x / x0)%expr +| ident.Z_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x mod x0)%expr +| ident.Z_log2 => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_log2)%expr @ x)%expr_pat +| ident.Z_log2_up => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_log2_up)%expr @ x)%expr_pat +| ident.Z_eqb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat +| ident.Z_leb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat +| ident.Z_geb => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat +| ident.Z_of_nat => + fun x : defaults.expr (type.base base.type.nat) => + UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat +| ident.Z_to_nat => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_to_nat)%expr @ x)%expr_pat +| ident.Z_shiftr => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x >> x0)%expr +| ident.Z_shiftl => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x << x0)%expr +| ident.Z_land => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x &' x0)%expr +| ident.Z_lor => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (x || x0)%expr +| ident.Z_bneg => + fun x : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_bneg)%expr @ x)%expr_pat +| ident.Z_lnot_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat +| ident.Z_mul_split => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat +| ident.Z_add_get_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x1 with + | #(_)%expr_pat => + match x0 with + | (@expr.App _ _ _ s0 _ #(idc1) x3 @ x2)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | ($_)%expr => + match x0 with + | (@expr.App _ _ _ s0 _ #(idc0) x3 @ x2)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | @expr.Abs _ _ _ _ _ _ => + match x0 with + | (@expr.App _ _ _ s1 _ #(idc0) x3 @ x2)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (#(_) @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s1 _ #(idc1) x4 @ x3)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (($_)%expr @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s1 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.Abs _ _ _ _ _ _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.App _ _ _ s0 _ #(idc0) x3 @ x2)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) + args1)%expr @ (x0, x' v))%expr_pat + else + match x0 with + | (@expr.App _ _ _ s2 _ #(idc2) x5 @ + x4)%expr_pat => + match + match idc2 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v1 : Z => + Some v1 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => + None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) + args3)%expr @ + (x1, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + (Compile.reflect x5) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + match + match idc2 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v1 : Z + => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) + (- args3))%expr @ + (x1, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end + (Compile.reflect + x5) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ + _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x3) + | None => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc2) x5 @ x4)%expr_pat => + match + match idc2 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc2 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) + _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + end + | ($_)%expr => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc1) x5 @ x4)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v0))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x1, x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | @expr.Abs _ _ _ _ _ _ => + match x0 with + | (@expr.App _ _ _ s3 _ #(idc1) x5 @ x4)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (_ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s3 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x0 with + | #(_)%expr_pat => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | ($_)%expr => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (#(_) @ _)%expr_pat => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (($_)%expr @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (@expr.Abs _ _ _ _ _ _ @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (@expr.App _ _ _ s2 _ #(idc1) x5 @ x4)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args2)%expr @ + (x1, x' v))%expr_pat + else + match x2 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v1 : Z + => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s0 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) + (- args3))%expr @ + (x0, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end + (Compile.reflect + x3) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + match x2 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x0, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + end + | ($_)%expr => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x0, x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x0, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x0, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args2))%expr @ + (x0, x' v))%expr_pat + else + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal + t5 v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v1 : Z => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base + t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) + (- args3))%expr @ + (x1, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end + (Compile.reflect + x5) + | None => + if + args =? + 2 + ^ Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + match x4 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp + t5 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v0 : Z => + Some v0 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 + ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 + ^ Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_get_carry)%expr @ + x @ x0 @ + x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + end + | ($_)%expr => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x1, x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) + (- args2))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 + args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' true + d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + end + | None => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + end + | None => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc1) x5 @ x4)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + args1)%expr @ + (x1, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc0) x5 @ x4)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s3 _ #(idc0) x5 @ x4)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s3 _ #(idc0) x6 @ x5)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s2 _ #(idc0) x6 @ x5)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | (@expr.LetIn _ _ _ _ _ _ _ @ _)%expr_pat => + match x0 with + | (@expr.App _ _ _ s1 _ #(idc0) x5 @ x4)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x0 with + | (@expr.App _ _ _ s0 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) args1)%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) + (- args1))%expr @ + (x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ + x0 @ x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ + x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_add (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add_with_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat +| ident.Z_add_with_get_carry => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | #(_)%expr_pat => + match x1 with + | (@expr.App _ _ _ s0 _ #(idc1) x4 @ x3)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | ($_)%expr => + match x1 with + | (@expr.App _ _ _ s0 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | @expr.Abs _ _ _ _ _ _ => + match x1 with + | (@expr.App _ _ _ s1 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (#(_) @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s1 _ #(idc1) x5 @ x4)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (($_)%expr @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s1 _ #(idc0) x5 @ x4)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s1 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (@expr.Abs _ _ _ _ _ _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc0) x5 @ x4)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (@expr.App _ _ _ s0 _ #(idc0) x4 @ x3)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + args1)%expr @ (x0, x1, x' v))%expr_pat + else + match x1 with + | (@expr.App _ _ _ s2 _ #(idc2) x6 @ + x5)%expr_pat => + match + match idc2 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v1 : Z => + Some v1 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => + None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) + args3)%expr @ + (x0, x2, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end + (Compile.reflect x6) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc2 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v1 : Z + => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) + (- args3))%expr @ + (x0, x2, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end + (Compile.reflect + x6) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ + _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc2) x6 @ x5)%expr_pat => + match + match idc2 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc2 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) + _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ + (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + end + | ($_)%expr => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v0))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x2, x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | @expr.Abs _ _ _ _ _ _ => + match x1 with + | (@expr.App _ _ _ s3 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | (_ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s3 _ #(idc1) x7 @ x6)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s3 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc1) x7 @ x6)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x1 with + | #(_)%expr_pat => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | ($_)%expr => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (#(_) @ _)%expr_pat => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (($_)%expr @ _)%expr_pat => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (@expr.Abs _ _ _ _ _ _ @ _)%expr_pat => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (@expr.App _ _ _ s2 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args2)%expr @ + (x0, x2, x' v))%expr_pat + else + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t5 + v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun v1 : Z + => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s0 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) + (- args3))%expr @ + (x0, x1, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end + (Compile.reflect + x4) + | None => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + match x3 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | ($_)%expr => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s0 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x1, x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args2))%expr @ + (x0, x1, x' v))%expr_pat + else + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal + t5 v0 => + match + t5 as t6 + return + (base.base_interp + t6 -> + option Z) + with + | base.type.unit => + fun + _ : unit + => None + | base.type.Z => + fun + v1 : Z => + Some v1 + | base.type.bool => + fun + _ : bool + => None + | base.type.nat => + fun + _ : nat + => None + end v0 + | _ => None + end + with + | Some args3 => + match + s2 as t5 + return + (Compile.value' + false t5 -> + UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base + t5 => + fun + v0 : + defaults.expr + (type.base + t5) => + base.try_make_transport_cps + (fun + t6 : base.type + => + defaults.expr + (type.base + t6)) t5 + base.type.Z + (UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a0 : + option + (defaults.expr + (type.base + t5) -> + defaults.expr + (type.base + base.type.Z)) + => + match + a0 + with + | Some + x'0 => + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) + (- args3))%expr @ + (x0, x2, + x'0 v0))%expr_pat + else + if + args =? + 2 + ^ + Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + | None => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : + Compile.value' + false s3 -> + Compile.value' + true d3 + => + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end + (Compile.reflect + x6) + | None => + if + args =? + 2 + ^ Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + end + | _ => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + match x5 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp + t5 -> option Z) + with + | base.type.unit => + fun _ : unit => + None + | base.type.Z => + fun v0 : Z => + Some v0 + | base.type.bool => + fun _ : bool => + None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false + t4 -> + UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type + => + defaults.expr + (type.base t5)) + t4 base.type.Z + (UnderLets.UnderLets + base.type ident + var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 + ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x2, + x' v))%expr_pat + else + if + args =? + 2 + ^ Z.log2 + args + then + UnderLets.Base + (# + (ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, + x2))%expr_pat + else + UnderLets.Base + (# + (ident.Z_add_with_get_carry)%expr @ + x @ x0 @ + x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' + true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | ($_)%expr => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t4 v0 => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args2 => + match + s2 as t4 + return + (Compile.value' false t4 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t4 => + fun + v0 : defaults.expr + (type.base t4) + => + base.try_make_transport_cps + (fun t5 : base.type => + defaults.expr + (type.base t5)) t4 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t4) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x2, + x' v0))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' + false s3 -> + Compile.value' true + d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base + t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) + (- args2))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 + args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ + x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' + false s4 -> + Compile.value' true + d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | None => + match x3 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => match s0 as t3 return (Compile.value' false t3 -> UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) with | type.base t3 => - fun v0 : expr (type.base t3) => + fun v0 : defaults.expr (type.base t3) + => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 base.type.Z (UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s + match a with + | Some x' => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) (- args))%expr @ - (x, x'0 v0))%expr_pat + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v0))%expr_pat else - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat | None => UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat end) - | (s2 -> d1)%ptype => + | (s3 -> d3)%ptype => fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) - (- args))%expr @ (x, x' v))%expr_pat - else - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) - (- args0))%expr @ - (x0, x'0 v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add - (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + _ : Compile.value' false s3 -> + Compile.value' true d3 => UnderLets.Base - (#(ident.fancy_add (Z.log2 s) - (- args))%expr @ (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end (Compile.reflect x1) - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s1 _ (_ @ _)%expr_pat _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - end - | None => - match x with - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base - (#(ident.fancy_add (Z.log2 s) - (- args))%expr @ (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match x with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ => - match x with - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + end + | None => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc1) x6 @ x5)%expr_pat => + match + match idc1 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) + t3 base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + match + match idc1 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + with + | type.base t3 => + fun + v : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + (base.type.Z * + base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a with + | Some x' => + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if + args =? + 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 + => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) + _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => - match x with - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end end - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match x with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc0) x6 @ x5)%expr_pat => match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return (base.base_interp t4 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) args)%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) (- args))%expr @ - (x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s2 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) + => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v0))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_add (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end -| ident.Z_add_with_carry => - fun x x0 x1 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat -| ident.Z_add_with_get_carry => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat -| ident.Z_add_with_get_carry_concrete s => - fun x x0 x1 : expr (type.base base.type.Z) => - match x1 with - | #(_)%expr_pat => - match x0 with - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | ($_)%expr => - match x0 with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => + | (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s3 _ #(idc0) x6 @ x5)%expr_pat => match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match x0 with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s3 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s4 -> d4)%ptype => + fun + _ : Compile.value' false s4 -> + Compile.value' true d4 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x0, x' v))%expr_pat - else - match x0 with - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x3 => + | (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s3 _ #(idc0) x7 @ x6)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc1)%expr_pat => match - match idc0 with - | ident.Z_shiftl offset => Some offset + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with - | Some args0 => + | Some args1 => match - s1 as t3 + s3 as t2 return - (Compile.value' false t3 -> + (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) with - | type.base t3 => - fun v0 : expr (type.base t3) => + | type.base t2 => + fun v : defaults.expr (type.base t2) => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z (UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) - args0)%expr @ - (x, x1, x'0 v0))%expr_pat + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat else - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) - 0)%expr @ (x, x0, x1))%expr_pat + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat | None => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat end) - | (s2 -> d1)%ptype => + | (s4 -> d4)%ptype => fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => + _ : Compile.value' false s4 -> + Compile.value' true d4 => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x6 with + | #(idc1)%expr_pat => match - match idc0 with - | ident.Z_shiftr offset => Some offset + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with - | Some args0 => + | Some args1 => match - s1 as t3 + s3 as t2 return - (Compile.value' false t3 -> + (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) with - | type.base t3 => - fun v0 : expr (type.base t3) => + | type.base t2 => + fun v : defaults.expr (type.base t2) + => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z (UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s + match a with + | Some x' => + if args =? 2 ^ Z.log2 args then UnderLets.Base (#(ident.fancy_addc - (Z.log2 s) (- args0))%expr @ - (x, x1, x'0 v0))%expr_pat + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat else - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base (#(ident.fancy_addc - (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat | None => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat end) - | (s2 -> d1)%ptype => + | (s4 -> d4)%ptype => fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => + _ : Compile.value' false s4 -> + Compile.value' true d4 => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) | None => - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ - s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 - _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match x0 with - | #(_)%expr_pat => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.Abs _ _ _ _ _ _ => + end + | (@expr.App _ _ _ s3 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s3 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s2 _ #(idc0) x7 @ x6)%expr_pat => match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x6 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s2 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s3 -> d3)%ptype => + fun + _ : Compile.value' false s3 -> + Compile.value' true d3 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x3 => - match - match idc0 with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args0 => + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args0)%expr @ - (x, x1, x' v))%expr_pat - else + | Some _ => + match x6 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => match - s0 as t3 + s2 as t2 return - (Compile.value' false t3 -> + (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) with - | type.base t3 => - fun v0 : expr (type.base t3) => + | type.base t2 => + fun v : defaults.expr (type.base t2) + => base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 base.type.Z (UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s + match a with + | Some x' => + if args =? 2 ^ Z.log2 args then UnderLets.Base (#(ident.fancy_addc - (Z.log2 s) (- args))%expr @ - (x, x0, x'0 v0))%expr_pat + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat else - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base (#(ident.fancy_addc - (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat | None => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat end) - | (s2 -> d1)%ptype => + | (s3 -> d3)%ptype => fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc0 with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) - (- args))%expr @ (x, x0, x' v))%expr_pat - else - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc - (Z.log2 s) - (- args0))%expr @ - (x, x1, x'0 v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc - (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + _ : Compile.value' false s3 -> + Compile.value' true d3 => UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) - (- args))%expr @ (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s1 _ (_ @ _)%expr_pat _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x7) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s2 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | (@expr.LetIn _ _ _ _ _ _ _ @ _)%expr_pat => + match x1 with + | (@expr.App _ _ _ s1 _ #(idc0) x6 @ x5)%expr_pat => match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + match + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end + with + | Some _ => + match x5 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s1 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x6) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s1 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat end - | None => - match x0 with - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x3 => + | @expr.LetIn _ _ _ _ _ _ _ => + match x1 with + | (@expr.App _ _ _ s0 _ #(idc0) x5 @ x4)%expr_pat => match match idc0 with - | ident.Z_shiftl offset => Some offset + | ident.Z_shiftl => Some tt | _ => None end with - | Some args => + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) args1)%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x4 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return + (base.base_interp t3 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) + => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr + (type.base t2) -> + defaults.expr + (type.base base.type.Z)) + => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) + (- args1))%expr @ + (x0, x2, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x5) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => + (#(ident.Z_add_with_get_carry)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_addc (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end +| ident.Z_sub_get_borrow => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x1 with + | (@expr.App _ _ _ s0 _ #(idc0) x3 @ x2)%expr_pat => + match + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end + with + | Some _ => + match x2 with + | #(idc1)%expr_pat => match - match idc0 with - | ident.Z_shiftr offset => Some offset + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with - | Some args => + | Some args1 => match - s1 as t2 + s0 as t2 return (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) with | type.base t2 => - fun v : expr (type.base t2) => + fun v : defaults.expr (type.base t2) => base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z (UnderLets.UnderLets base.type ident var - (expr + (defaults.expr (type.base (base.type.Z * base.type.Z)%etype))) (fun a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => match a with | Some x' => - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) - (- args))%expr @ (x, x1, x' v))%expr_pat + (#(ident.fancy_sub (Z.log2 args) + args1)%expr @ (x0, x' v))%expr_pat else - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_sub_get_borrow)%expr @ + x @ x0 @ x1)%expr_pat | None => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat + (#(ident.Z_sub_get_borrow)%expr @ x @ + x0 @ x1)%expr_pat end) - | (s2 -> d1)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s2 -> + _ : Compile.value' false s1 -> Compile.value' true d1 => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ + x1)%expr_pat end (Compile.reflect x3) | None => - if s =? 2 ^ Z.log2 s + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match x0 with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => + | None => match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v0))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub + (Z.log2 args) (- args1))%expr @ + (x0, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub + (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ + x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ + x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ + x1)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_sub (Z.log2 args) 0)%expr @ (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ => - match x0 with - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => + | _ => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_sub_with_get_borrow => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x2 with + | (@expr.App _ _ _ s0 _ #(idc0) x4 @ x3)%expr_pat => match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftl => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) + args1)%expr @ (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) + 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end + | None => match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | ident.Z_shiftr => Some tt + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base + (base.type.Z * base.type.Z)%etype))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb + (Z.log2 args) (- args1))%expr @ + (x0, x1, x' v))%expr_pat + else + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb + (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end (Compile.reflect x4) + | None => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => - match x0 with - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x4 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s + (#(ident.Z_sub_with_get_borrow)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + if args =? 2 ^ Z.log2 args then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat else UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x4) - | None => + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | None => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ + (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end + end + | (@expr.App _ _ _ s0 _ ($_)%expr _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (_ @ _) _ @ _)%expr_pat | + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ @ _)%expr_pat => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | _ => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_subb (Z.log2 args) 0)%expr @ (x0, x1, x2))%expr_pat + else + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end +| ident.Z_zselect => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x3) x2 => + match match idc with + | ident.Z_cc_m => Some tt + | _ => None + end with + | Some _ => + match x3 with + | #(idc0)%expr_pat => match - match idc with - | ident.Z_shiftr offset => Some offset + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with - | Some args => + | Some args0 => match - s2 as t2 + s as t2 return (Compile.value' false t2 -> UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + (defaults.expr (type.base base.type.Z))) with | type.base t2 => - fun v : expr (type.base t2) => + fun v : defaults.expr (type.base t2) => base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z + (fun t1 : base.type => defaults.expr (type.base t1)) + t2 base.type.Z (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + (defaults.expr (type.base base.type.Z))) (fun a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) => match a with | Some x' => - if s =? 2 ^ Z.log2 s + if args0 =? 2 ^ Z.log2 args0 then UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat + (#(ident.fancy_selm (Z.log2 args0))%expr @ + (x' v, x0, x1))%expr_pat else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat | None => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat end) - | (s3 -> d2)%ptype => + | (s1 -> d1)%ptype => fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x4) + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match x0 with - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x4 => + | None => match match idc with - | ident.Z_shiftl offset => Some offset + | ident.Z_land => Some tt | _ => None end with - | Some args => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x4) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => + | Some _ => + match x3 with + | #(idc0)%expr_pat => match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + | Some args0 => + match + s as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base base.type.Z)) + => + match a with + | Some x' => + if args0 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x' v, x0, x1))%expr_pat + else + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t3 v0 => + match + t3 as t4 + return + (base.base_interp t4 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v1 : Z => Some v1 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v0 + | _ => None + end + with + | Some args1 => + match + s0 as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base base.type.Z))) + with + | type.base t3 => + fun + v0 : defaults.expr + (type.base t3) => + base.try_make_transport_cps + (fun t4 : base.type => + defaults.expr + (type.base t4)) t3 + base.type.Z + (UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base + base.type.Z))) + (fun + a0 : option + (defaults.expr + (type.base t3) -> + defaults.expr + (type.base + base.type.Z)) + => + match a0 with + | Some x'0 => + if args1 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x'0 v0, x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ + x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 + => + UnderLets.Base + (#(ident.Z_zselect)%expr @ + x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x2) + | None => + match x2 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident + var + (defaults.expr + (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x' v, x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ + x0 @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + end + | ($_)%expr => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t2 v0 => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v1 : Z => Some v1 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v0 + | _ => None + end + with + | Some args0 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v0 : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t3 : base.type => + defaults.expr (type.base t3)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x' v0, x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ + x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | @expr.LetIn _ _ _ _ _ _ _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 + return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x' v, x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ + x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun + _ : Compile.value' false s1 -> + Compile.value' true d1 => UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x4) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x0 with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) args)%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 + return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + base.try_make_transport_cps + (fun t1 : base.type => + defaults.expr (type.base t1)) t2 + base.type.Z + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.Z))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr + (type.base base.type.Z)) => + match a with + | Some x' => + if args0 =? 1 + then + UnderLets.Base + (#(ident.fancy_sell)%expr @ + (x' v, x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.fancy_selc)%expr @ + (x, x0, x1))%expr_pat + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ + x1)%expr_pat + end) + | (s2 -> d2)%ptype => + fun + _ : Compile.value' false s2 -> + Compile.value' true d2 => UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) (- args))%expr @ - (x, x1, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end + | _ => UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + end end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_addc (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - end -| ident.Z_sub_get_borrow => - fun x x0 x1 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat -| ident.Z_sub_get_borrow_concrete s => - fun x x0 : expr (type.base base.type.Z) => - match x0 with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) args)%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) (- args))%expr @ - (x, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) 0)%expr @ - (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_sub (Z.log2 s) 0)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end -| ident.Z_sub_with_get_borrow => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat -| ident.Z_sub_with_get_borrow_concrete s => - fun x x0 x1 : expr (type.base base.type.Z) => - match x1 with - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_shiftl offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) args)%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 => UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_shiftr offset => Some offset - | _ => None - end - with - | Some args => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) (- args))%expr @ - (x, x0, x' v))%expr_pat - else - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) 0)%expr @ - (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ - x1)%expr_pat + (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat end end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_subb (Z.log2 s) 0)%expr @ (x, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ x1)%expr_pat + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat end -| ident.Z_zselect => - fun x x0 x1 : expr (type.base base.type.Z) => +| ident.Z_add_modulo => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + UnderLets.Base (#(ident.fancy_addm)%expr @ (x, x0, x1))%expr_pat +| ident.Z_rshi => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => match x with - | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => + | #(idc)%expr_pat => match match idc with - | ident.Z_cc_m_concrete s0 => Some s0 + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v | _ => None end with | Some args => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? 2 ^ Z.log2 args - then - UnderLets.Base - (#(ident.fancy_selm (Z.log2 args))%expr @ - (x' v, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat - | None => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - match - match idc with - | ident.Z_land mask => Some mask - | _ => None - end - with - | Some args => + match x2 with + | #(idc0)%expr_pat => match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? 1 - then - UnderLets.Base - (#(ident.fancy_sell)%expr @ (x' v, x0, x1))%expr_pat - else - UnderLets.Base - (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat - | None => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => + | Some args0 => + if args =? 2 ^ Z.log2 args + then + UnderLets.Base + (#(ident.fancy_rshi (Z.log2 args) args0)%expr @ + (x0, x1))%expr_pat + else + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + | None => UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => UnderLets.Base - (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat end + | None => + UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat - | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ (x, x0, x1))%expr_pat + | _ => UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat end -| ident.Z_add_modulo => - fun x x0 x1 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.fancy_addm)%expr @ (x, x0, x1))%expr_pat -| ident.Z_rshi => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat -| ident.Z_rshi_concrete s offset => - fun x x0 : expr (type.base base.type.Z) => - if s =? 2 ^ Z.log2 s - then - UnderLets.Base - (#(ident.fancy_rshi (Z.log2 s) offset)%expr @ (x, x0))%expr_pat - else - UnderLets.Base - (#(ident.Z_rshi_concrete s offset)%expr @ x @ x0)%expr_pat | ident.Z_cc_m => - fun x x0 : expr (type.base base.type.Z) => + fun x x0 : defaults.expr (type.base base.type.Z) => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat -| ident.Z_cc_m_concrete s => - fun x : expr (type.base base.type.Z) => - UnderLets.Base (#(ident.Z_cc_m_concrete s)%expr @ x)%expr_pat -| ident.Z_neg_snd => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base (#(ident.Z_neg_snd)%expr @ x)%expr_pat | ident.Z_cast range => - fun x : expr (type.base base.type.Z) => + fun x : defaults.expr (type.base base.type.Z) => UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat | ident.Z_cast2 range => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat | ident.fancy_add log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat | ident.fancy_addc log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat | ident.fancy_sub log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat | ident.fancy_subb log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat | ident.fancy_mulll log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat | ident.fancy_mullh log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat | ident.fancy_mulhl log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat | ident.fancy_mulhh log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat | ident.fancy_rshi log2wordmax x => - fun x0 : expr (type.base (base.type.Z * base.type.Z)%etype) => + fun x0 : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => UnderLets.Base (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat | ident.fancy_selc => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat | ident.fancy_selm log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat | ident.fancy_sell => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat | ident.fancy_addm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat end : Compile.value' true t diff --git a/src/Experiments/NewPipeline/nbe_rewrite_head.out b/src/Experiments/NewPipeline/nbe_rewrite_head.out new file mode 100644 index 000000000..82d4983bd --- /dev/null +++ b/src/Experiments/NewPipeline/nbe_rewrite_head.out @@ -0,0 +1,5123 @@ +nbe_rewrite_head = +match idc in (ident t) return (Compile.value' true t) with +| @ident.Literal t v => + match + t as t0 + return + (base.base_interp t0 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base t0))) + with + | base.type.unit => fun v0 : unit => UnderLets.Base ##(v0)%expr + | base.type.Z => fun v0 : Z => UnderLets.Base ##(v0)%expr + | base.type.bool => fun v0 : bool => UnderLets.Base ##(v0)%expr + | base.type.nat => fun v0 : nat => UnderLets.Base ##(v0)%expr + end v +| ident.Nat_succ => + fun x : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Nat.succ args)%expr + | None => UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat + end +| ident.Nat_pred => + fun x : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Nat.pred args)%expr + | None => UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat + end +| ident.Nat_max => + fun x x0 : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option nat) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(Nat.max args args0)%expr + | None => + UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat + end +| ident.Nat_mul => + fun x x0 : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option nat) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args * args0)%nat)%expr + | None => + UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat + end +| ident.Nat_add => + fun x x0 : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option nat) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args + args0)%nat)%expr + | None => + UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat + end +| ident.Nat_sub => + fun x x0 : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option nat) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args - args0)%nat)%expr + | None => + UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat + end +| @ident.nil t => UnderLets.Base []%expr_pat +| @ident.cons t => + fun (x : defaults.expr (type.base t)) + (x0 : defaults.expr (type.base (base.type.list t))) => + UnderLets.Base (x :: x0)%expr_pat +| @ident.pair A B => + fun (x : defaults.expr (type.base A)) (x0 : defaults.expr (type.base B)) + => UnderLets.Base (x, x0)%expr_pat +| @ident.fst A B => + fun x : defaults.expr (type.base (A * B)%etype) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => + match + match idc with + | @ident.pair A0 B0 => Some (A0, B0) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + with + | type.base t3 => + fun _ : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t2 + A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (fun + a : option + (defaults.expr (type.base t2) -> + defaults.expr (type.base A)) => + match a with + | Some x' => UnderLets.Base (x' v) + | None => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end (Compile.reflect x0) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end (Compile.reflect x1) + | None => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + | _ => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat + end +| @ident.snd A B => + fun x : defaults.expr (type.base (A * B)%etype) => + match x with + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => + match + match idc with + | @ident.pair A0 B0 => Some (A0, B0) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + with + | type.base t2 => + fun _ : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) t3 + B + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + (fun + a : option + (defaults.expr (type.base t3) -> + defaults.expr (type.base B)) => + match a with + | Some x' => UnderLets.Base (x' v0) + | None => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end (Compile.reflect x0) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end (Compile.reflect x1) + | None => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App + _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ + s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ + (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + | _ => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat + end +| @ident.prod_rect A B T => + fun + (x : defaults.expr (type.base A) -> + defaults.expr (type.base B) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x0 : defaults.expr (type.base (A * B)%etype)) => + match x0 with + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x2 : var (type.base A))(x3 : var (type.base B)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0)%expr_pat + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x2) x1 => + match + match idc with + | @ident.pair A0 B0 => Some (A0, B0) + | _ => None + end + with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + Compile.castbe v + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun x3 : option (defaults.expr (type.base A)) => + match x3 with + | Some x4 => + Compile.castbe v0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun y : option (defaults.expr (type.base B)) => + match y with + | Some y0 => + (fv <-- (e <-- x x4 y0; + UnderLets.Base + {| + anyexpr_ty := T; + unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + T + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := + fv in + anyexpr_ty)) -> + defaults.expr (type.base T)) + => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let + (anyexpr_ty, + _) := a0 in + anyexpr_ty))) := + fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x5 : var (type.base A)) + (x6 : var (type.base B)), + UnderLets.to_expr + (x ($x5) ($x6)))%expr @ x0)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x5 : var (type.base A))(x6 : + var + (type.base + B)), + UnderLets.to_expr (x ($x5) ($x6)))%expr @ + x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base B)), + UnderLets.to_expr (x ($x4) ($x5)))%expr @ x0)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x3 : var (type.base A))(x4 : var (type.base B)), + UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat + end (Compile.reflect x1) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x3 : var (type.base A))(x4 : var (type.base B)), + UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat + end (Compile.reflect x2) + | None => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x3 : var (type.base A))(x4 : var (type.base B)), + UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x3 : var (type.base A))(x4 : var (type.base B)), + UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s _ + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x4 : var (type.base A))(x5 : var (type.base B)), + UnderLets.to_expr (x ($x4) ($x5)))%expr @ x0)%expr_pat + | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x3 : var (type.base A))(x4 : var (type.base B)), + UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat + | @expr.LetIn _ _ _ _ _ _ _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x2 : var (type.base A))(x3 : var (type.base B)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0)%expr_pat + | _ => + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ (x1 : var (type.base A))(x2 : var (type.base B)), + UnderLets.to_expr (x ($x1) ($x2)))%expr @ x0)%expr_pat + end +| @ident.bool_rect T => + fun + (x + x0 : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base base.type.bool)) => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option bool) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun v0 : bool => Some v0 + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + (fv <-- (e <-- (if args as b + return + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (if b then T else T)))) + then x ##(tt)%expr + else x0 ##(tt)%expr); + UnderLets.Base + {| anyexpr_ty := if args then T else T; unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) T + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base T)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in anyexpr_ty))) := + fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.bool_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.bool_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end + | ($_)%expr | @expr.Abs _ _ _ _ _ _ => + UnderLets.Base + (#(ident.bool_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + | _ => + UnderLets.Base + (#(ident.bool_rect)%expr @ + (λ x3 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x3)))%expr @ + (λ x3 : var (type.base base.type.unit), + UnderLets.to_expr (x0 ($x3)))%expr @ x1)%expr_pat + end +| @ident.nat_rect P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base base.type.nat) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base base.type.nat)) => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + Compile.castv x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + S_case : option + (defaults.expr (type.base base.type.nat) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) => + match S_case with + | Some S_case0 => + (fv <-- (e <-- nat_rect + (fun _ : nat => + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x ##(tt)%expr) + (fun (n' : nat) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr (type.base P))) + => rec0 <-- rec; + S_case0 ##(n')%expr rec0) args; + UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) P + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base P)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base base.type.nat)) + (x3 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base base.type.nat))(x3 : var + (type.base + P)), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end + | ($_)%expr | @expr.Abs _ _ _ _ _ _ => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + | _ => + UnderLets.Base + (#(ident.nat_rect)%expr @ + (λ x3 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var (type.base P)), + UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat + end +| @ident.nat_rect_arrow P Q => + fun + (x : defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x0 : defaults.expr (type.base base.type.nat) -> + (defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (x1 : defaults.expr (type.base base.type.nat)) + (x2 : defaults.expr (type.base P)) => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + Compile.castv x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (fun + S_case : option + (defaults.expr (type.base base.type.nat) -> + (defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) => + match S_case with + | Some S_case0 => + Compile.castbe x2 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (fun v : option (defaults.expr (type.base P)) => + match v with + | Some v0 => + (fv <-- (e <-- nat_rect + (fun _ : nat => + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type + ident var + (defaults.expr (type.base Q))) + x + (fun (n' : nat) + (rec : defaults.expr + (type.base P) -> + UnderLets.UnderLets + base.type ident var + (defaults.expr + (type.base Q))) + (v1 : defaults.expr + (type.base P)) => + S_case0 ##(n')%expr rec v1) args + v0; + UnderLets.Base + {| anyexpr_ty := Q; unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) Q + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base Q))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in + anyexpr_ty)) -> + defaults.expr (type.base Q)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := + a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat)) + (x4 : var + (type.base P -> type.base Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun + x6 : defaults.expr + (type.base P) => + UnderLets.Base + ($x4 @ x6)%expr_pat) ($x5)))%expr @ + x1 @ x2)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : + var + (type.base + P -> + type.base + Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) + ($x5)))%expr @ x1 @ x2)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var + (type.base + P -> + type.base + Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) ($x5)))%expr @ + x1 @ x2)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var + (type.base P -> + type.base Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) ($x5)))%expr @ x1 @ + x2)%expr_pat + end + | ($_)%expr | @expr.Abs _ _ _ _ _ _ => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x3 : var (type.base P), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base base.type.nat))(x4 : var + (type.base P -> + type.base Q)%ptype) + (x5 : var (type.base P)), + UnderLets.to_expr + (x0 ($x3) + (fun x6 : defaults.expr (type.base P) => + UnderLets.Base ($x4 @ x6)%expr_pat) ($x5)))%expr @ x1 @ x2)%expr_pat + | _ => + UnderLets.Base + (#(ident.nat_rect_arrow)%expr @ + (λ x4 : var (type.base P), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base base.type.nat))(x5 : var + (type.base P -> + type.base Q)%ptype) + (x6 : var (type.base P)), + UnderLets.to_expr + (x0 ($x4) + (fun x7 : defaults.expr (type.base P) => + UnderLets.Base ($x5 @ x7)%expr_pat) ($x6)))%expr @ x1 @ x2)%expr_pat + end +| @ident.list_rect A P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => + Compile.castv x0 + (UnderLets.UnderLets base.type ident var (defaults.expr (type.base P))) + (fun + Pcons : option + (defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base P) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) => + match Pcons with + | Some Pcons0 => + reflect_list_cps x1 + (fun ls : option (list (defaults.expr (type.base A))) => + match ls with + | Some ls0 => + (fv <-- (e <-- list_rect + (fun + _ : list (defaults.expr (type.base A)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x ##(tt)%expr) + (fun (x2 : defaults.expr (type.base A)) + (xs : list + (defaults.expr (type.base A))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr (type.base P))) + => + rec' <-- rec; + Pcons0 x2 (reify_list xs) rec') ls0; + UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) P + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base P)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.list_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base + (base.type.list + A))) + (x4 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ + x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.list_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base + (base.type.list A))) + (x4 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.list_rect)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base + (base.type.list A))) + (x4 : var (type.base P)), + UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat + end) +| @ident.list_case A P => + fun + (x : defaults.expr (type.base base.type.unit) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x0 : defaults.expr (type.base A) -> + defaults.expr (type.base (base.type.list A)) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (x1 : defaults.expr (type.base (base.type.list A))) => + match x1 with + | #(idc)%expr_pat => + match match idc with + | @ident.nil t0 => Some t0 + | _ => None + end with + | Some _ => + (fv <-- (e <-- x ##(tt)%expr; + UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) P + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base P)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in anyexpr_ty))) := + fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base + (base.type.list + A))), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base + (base.type.list A))), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end + | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | + @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x3 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base A))(x4 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x3) x2 => + match match idc with + | @ident.cons t0 => Some t0 + | _ => None + end with + | Some _ => + match + s0 as t2 + return + (Compile.value' false t2 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + with + | type.base t2 => + fun v : defaults.expr (type.base t2) => + match + s as t3 + return + (Compile.value' false t3 -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + with + | type.base t3 => + fun v0 : defaults.expr (type.base t3) => + Compile.castbe v + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun x4 : option (defaults.expr (type.base A)) => + match x4 with + | Some x5 => + Compile.castbe v0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + xs : option + (defaults.expr + (type.base (base.type.list A))) => + match xs with + | Some xs0 => + (fv <-- (e <-- x0 x5 xs0; + UnderLets.Base + {| + anyexpr_ty := P; + unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + P + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base P))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := + fv in + anyexpr_ty)) -> + defaults.expr (type.base P)) + => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let + (anyexpr_ty, + _) := a0 in + anyexpr_ty))) := + fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x6 : var + (type.base + base.type.unit), + UnderLets.to_expr (x ($x6)))%expr @ + (λ (x6 : var (type.base A)) + (x7 : var + (type.base + (base.type.list A))), + UnderLets.to_expr + (x0 ($x6) ($x7)))%expr @ x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x6 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x6)))%expr @ + (λ (x6 : var (type.base A))(x7 : + var + (type.base + (base.type.list + A))), + UnderLets.to_expr (x0 ($x6) ($x7)))%expr @ + x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x5 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x5)))%expr @ + (λ (x5 : var (type.base A))(x6 : var + (type.base + (base.type.list + A))), + UnderLets.to_expr (x0 ($x5) ($x6)))%expr @ x1)%expr_pat + end) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 + => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x4 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base + (base.type.list + A))), + UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat + end (Compile.reflect x2) + | (s1 -> d1)%ptype => + fun _ : Compile.value' false s1 -> Compile.value' true d1 => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x4 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base + (base.type.list A))), + UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat + end (Compile.reflect x3) + | None => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x4 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base + (base.type.list A))), + UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat + end + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ + _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x4 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat + | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | + @expr.App _ _ _ s _ + (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x5 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x5)))%expr @ + (λ (x5 : var (type.base A))(x6 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x5) ($x6)))%expr @ x1)%expr_pat + | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x4 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x4)))%expr @ + (λ (x4 : var (type.base A))(x5 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat + | @expr.LetIn _ _ _ _ _ _ _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x3 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x3)))%expr @ + (λ (x3 : var (type.base A))(x4 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat + | _ => + UnderLets.Base + (#(ident.list_case)%expr @ + (λ x2 : var (type.base base.type.unit), + UnderLets.to_expr (x ($x2)))%expr @ + (λ (x2 : var (type.base A))(x3 : var + (type.base (base.type.list A))), + UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat + end +| @ident.List_length T => + fun x : defaults.expr (type.base (base.type.list T)) => + reflect_list_cps x + (fun xs : option (list (defaults.expr (type.base T))) => + match xs with + | Some xs0 => UnderLets.Base ##(length xs0)%expr + | None => UnderLets.Base (#(ident.List_length)%expr @ x)%expr_pat + end) +| ident.List_seq => + fun x x0 : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option nat) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args0 => + UnderLets.Base + (fold_right + (fun (x1 : defaults.expr (type.base base.type.nat)) + (xs : defaults.expr + (type.base (base.type.list base.type.nat))) + => (x1 :: xs)%expr_pat) []%expr_pat + (map (fun v : nat => ##(v)%expr) (seq args args0))) + | None => + UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat + end +| @ident.List_firstn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + reflect_list_cps x0 + (fun xs : option (list (defaults.expr (type.base A))) => + match xs with + | Some xs0 => + base.try_make_transport_cps + (fun A0 : base.type => + defaults.expr (type.base (base.type.list A0))) A A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun + a : option + (defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base (base.type.list A))) + => + match a with + | Some x' => + UnderLets.Base (x' (reify_list (firstn args xs0))) + | None => + UnderLets.Base + (#(ident.List_firstn)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_firstn)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base (#(ident.List_firstn)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.List_firstn)%expr @ x @ x0)%expr_pat + end +| @ident.List_skipn A => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base (base.type.list A))) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + reflect_list_cps x0 + (fun xs : option (list (defaults.expr (type.base A))) => + match xs with + | Some xs0 => + base.try_make_transport_cps + (fun A0 : base.type => + defaults.expr (type.base (base.type.list A0))) A A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun + a : option + (defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base (base.type.list A))) + => + match a with + | Some x' => + UnderLets.Base (x' (reify_list (skipn args xs0))) + | None => + UnderLets.Base + (#(ident.List_skipn)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_skipn)%expr @ x @ x0)%expr_pat + end) + | None => UnderLets.Base (#(ident.List_skipn)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.List_skipn)%expr @ x @ x0)%expr_pat + end +| @ident.List_repeat A => + fun (x : defaults.expr (type.base A)) + (x0 : defaults.expr (type.base base.type.nat)) => + match x0 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + base.try_make_transport_cps + (fun A0 : base.type => + defaults.expr (type.base (base.type.list A0))) A A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun + a : option + (defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base (base.type.list A))) => + match a with + | Some x' => UnderLets.Base (x' (reify_list (repeat x args))) + | None => + UnderLets.Base + (#(ident.List_repeat)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat + end +| @ident.List_combine A B => + fun (x : defaults.expr (type.base (base.type.list A))) + (x0 : defaults.expr (type.base (base.type.list B))) => + reflect_list_cps x + (fun xs : option (list (defaults.expr (type.base A))) => + match xs with + | Some xs0 => + reflect_list_cps x0 + (fun ys : option (list (defaults.expr (type.base B))) => + match ys with + | Some ys0 => + (trA <-- base.try_make_transport_cps + (fun A0 : base.type => + defaults.expr + (type.base (base.type.list (A0 * B)))) A A; + trB <-- base.try_make_transport_cps + (fun B0 : base.type => + defaults.expr + (type.base (base.type.list (A * B0)))) B B; + return Some + (fun + v : defaults.expr + (type.base (base.type.list (A * B))) => + trB (trA v)))%cps + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list (A * B))))) + (fun + a : option + (defaults.expr + (type.base (base.type.list (A * B))) -> + defaults.expr + (type.base (base.type.list (A * B)))) => + match a with + | Some x' => + UnderLets.Base + (x' + (reify_list + (map (fun '(x1, y) => (x1, y)%expr_pat) + (combine xs0 ys0)))) + | None => + UnderLets.Base + (#(ident.List_combine)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_combine)%expr @ x @ x0)%expr_pat + end) + | None => + UnderLets.Base (#(ident.List_combine)%expr @ x @ x0)%expr_pat + end) +| @ident.List_map A B => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base B))) + (x0 : defaults.expr (type.base (base.type.list A))) => + Compile.castbe x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (fun e : option (defaults.expr (type.base (base.type.list A))) => + match e with + | Some e0 => + reflect_list_cps e0 + (fun ls : option (list (defaults.expr (type.base A))) => + match ls with + | Some ls0 => + (fv <-- (e1 <-- list_rect + (fun + _ : list (defaults.expr (type.base A)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.list B)))) + (UnderLets.Base []%expr_pat) + (fun (x1 : defaults.expr (type.base A)) + (_ : list + (defaults.expr (type.base A))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.list B)))) + => + rec' <-- rec; + fx <-- x x1; + UnderLets.Base (fx :: rec')%expr_pat) + ls0; + UnderLets.Base + {| + anyexpr_ty := base.type.list B; + unwrap := e1 |}); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + (base.type.list B) + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base (base.type.list B))) + => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.List_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.List_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) +| @ident.List_app A => + fun x x0 : defaults.expr (type.base (base.type.list A)) => + Compile.castbe x + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun e : option (defaults.expr (type.base (base.type.list A))) => + match e with + | Some e0 => + reflect_list_cps e0 + (fun ls : option (list (defaults.expr (type.base A))) => + match ls with + | Some ls0 => + (fv <-- (e1 <-- list_rect + (fun + _ : list (defaults.expr (type.base A)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.list A)))) + (UnderLets.Base x0) + (fun (x1 : defaults.expr (type.base A)) + (_ : list + (defaults.expr (type.base A))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.list A)))) + => + rec' <-- rec; + UnderLets.Base (x1 :: rec')%expr_pat) + ls0; + UnderLets.Base + {| + anyexpr_ty := base.type.list A; + unwrap := e1 |}); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + (base.type.list A) + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base (base.type.list A))) + => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => UnderLets.Base (x ++ x0)%expr + end))%under_lets + | None => UnderLets.Base (x ++ x0)%expr + end) + | None => UnderLets.Base (x ++ x0)%expr + end) +| @ident.List_rev A => + fun x : defaults.expr (type.base (base.type.list A)) => + reflect_list_cps x + (fun xs : option (list (defaults.expr (type.base A))) => + match xs with + | Some xs0 => + base.try_make_transport_cps + (fun A0 : base.type => + defaults.expr (type.base (base.type.list A0))) A A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list A)))) + (fun + a : option + (defaults.expr (type.base (base.type.list A)) -> + defaults.expr (type.base (base.type.list A))) => + match a with + | Some x' => UnderLets.Base (x' (reify_list (rev xs0))) + | None => UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat + end) + | None => UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat + end) +| @ident.List_flat_map A B => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (x0 : defaults.expr (type.base (base.type.list A))) => + Compile.castbe x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (fun e : option (defaults.expr (type.base (base.type.list A))) => + match e with + | Some e0 => + reflect_list_cps e0 + (fun ls : option (list (defaults.expr (type.base A))) => + match ls with + | Some ls0 => + (fv <-- (e1 <-- list_rect + (fun + _ : list (defaults.expr (type.base A)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.list B)))) + (UnderLets.Base []%expr_pat) + (fun (x1 : defaults.expr (type.base A)) + (_ : list + (defaults.expr (type.base A))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.list B)))) + => + rec' <-- rec; + fx <-- x x1; + UnderLets.Base ($fx ++ rec')%expr) ls0; + UnderLets.Base + {| + anyexpr_ty := base.type.list B; + unwrap := e1 |}); + fv0 <-- do_again (let (anyexpr_ty, _) := fv in anyexpr_ty) + (let + (anyexpr_ty, unwrap) as a + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a in + anyexpr_ty))) := fv in + unwrap); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + (base.type.list B) + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list B)))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base (base.type.list B))) + => + match a with + | Some x' => UnderLets.Base (x' fv0) + | None => + UnderLets.Base + (#(ident.List_flat_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.List_flat_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_flat_map)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) +| @ident.List_partition A => + fun + (x : defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base base.type.bool))) + (x0 : defaults.expr (type.base (base.type.list A))) => + Compile.castbe x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base (base.type.list A * base.type.list A)%etype))) + (fun e : option (defaults.expr (type.base (base.type.list A))) => + match e with + | Some e0 => + reflect_list_cps e0 + (fun ls : option (list (defaults.expr (type.base A))) => + match ls with + | Some ls0 => + (fv <-- (e1 <-- list_rect + (fun + _ : list (defaults.expr (type.base A)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.list A * + base.type.list A)%etype))) + (UnderLets.Base ([], [])%expr_pat) + (fun (x1 : defaults.expr (type.base A)) + (_ : list + (defaults.expr (type.base A))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr + (type.base + (base.type.list A * + base.type.list A)%etype))) + => + rec' <-- rec; + fx <-- id x x1; + UnderLets.Base + (#(ident.prod_rect)%expr @ + (λ g + d : defaults.expr + (type.base + (base.type.list A)), + (#(ident.bool_rect)%expr @ + (λ _ : defaults.expr + (type.base base.type.unit), + ($x1 :: $g, $d)%expr_pat) @ + (λ _ : defaults.expr + (type.base base.type.unit), + ($g, $x1 :: $d)%expr_pat) @ $fx)%expr_pat)%expr @ + rec')%expr_pat) ls0; + UnderLets.Base + {| + anyexpr_ty := (base.type.list A * + base.type.list A)%etype; + unwrap := e1 |}); + fv0 <-- do_again (let (anyexpr_ty, _) := fv in anyexpr_ty) + (let + (anyexpr_ty, unwrap) as a + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a in + anyexpr_ty))) := fv in + unwrap); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + (base.type.list A * base.type.list A) + (UnderLets.UnderLets base.type ident var + (defaults.expr + (type.base + (base.type.list A * base.type.list A)%etype))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr + (type.base + (base.type.list A * base.type.list A)%etype)) + => + match a with + | Some x' => UnderLets.Base (x' fv0) + | None => + UnderLets.Base + (#(ident.List_partition)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.List_partition)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_partition)%expr @ + (λ x1 : var (type.base A), + UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat + end) +| @ident.List_fold_right A B => + fun + (x : defaults.expr (type.base B) -> + defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (x0 : defaults.expr (type.base A)) + (x1 : defaults.expr (type.base (base.type.list B))) => + Compile.castv x + (UnderLets.UnderLets base.type ident var (defaults.expr (type.base A))) + (fun + f : option + (defaults.expr (type.base B) -> + defaults.expr (type.base A) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) => + match f with + | Some f0 => + reflect_list_cps x1 + (fun ls : option (list (defaults.expr (type.base B))) => + match ls with + | Some ls0 => + (fv <-- (e <-- list_rect + (fun + _ : list (defaults.expr (type.base B)) + => + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (UnderLets.Base x0) + (fun (x2 : defaults.expr (type.base B)) + (_ : list (defaults.expr (type.base B))) + (rec : UnderLets.UnderLets base.type + ident var + (defaults.expr (type.base A))) + => rec' <-- rec; + f0 x2 rec') ls0; + UnderLets.Base {| anyexpr_ty := A; unwrap := e |}); + base.try_make_transport_cps + (fun t : base.type => defaults.expr (type.base t)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) A + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base A))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> + defaults.expr (type.base A)) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.List_fold_right)%expr @ + (λ (x2 : var (type.base B))(x3 : var + (type.base A)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ + x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.List_fold_right)%expr @ + (λ (x2 : var (type.base B))(x3 : var (type.base A)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_fold_right)%expr @ + (λ (x2 : var (type.base B))(x3 : var (type.base A)), + UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat + end) +| @ident.List_update_nth T => + fun (x : defaults.expr (type.base base.type.nat)) + (x0 : defaults.expr (type.base T) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (x1 : defaults.expr (type.base (base.type.list T))) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + Compile.castv x0 + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list T)))) + (fun + f : option + (defaults.expr (type.base T) -> + UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) => + match f with + | Some f0 => + reflect_list_cps x1 + (fun ls : option (list (defaults.expr (type.base T))) => + match ls with + | Some ls0 => + (fv <-- (e <-- (retv <---- update_nth args + (fun + x2 : UnderLets.UnderLets + base.type + ident var + (defaults.expr + (type.base + T)) => + x3 <-- x2; + f0 x3) + (map UnderLets.Base + ls0); + UnderLets.Base (reify_list retv)); + UnderLets.Base + {| + anyexpr_ty := base.type.list T; + unwrap := e |}); + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) + (let (anyexpr_ty, _) := fv in anyexpr_ty) + (base.type.list T) + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base (base.type.list T)))) + (fun + a : option + (defaults.expr + (type.base + (let (anyexpr_ty, _) := fv in + anyexpr_ty)) -> + defaults.expr + (type.base (base.type.list T))) => + match a with + | Some x' => + UnderLets.Base + (x' + (let + (anyexpr_ty, unwrap) as a0 + return + (defaults.expr + (type.base + (let (anyexpr_ty, _) := + a0 in + anyexpr_ty))) := fv in + unwrap)) + | None => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end))%under_lets + | None => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + end + | ($_)%expr | @expr.Abs _ _ _ _ _ _ => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x2 : var (type.base T), + UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat + | _ => + UnderLets.Base + (#(ident.List_update_nth)%expr @ x @ + (λ x3 : var (type.base T), + UnderLets.to_expr (x0 ($x3)))%expr @ x1)%expr_pat + end +| @ident.List_nth_default T => + fun (x : defaults.expr (type.base T)) + (x0 : defaults.expr (type.base (base.type.list T))) + (x1 : defaults.expr (type.base base.type.nat)) => + match x1 with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => + Compile.castbe x + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun default : option (defaults.expr (type.base T)) => + match default with + | Some default0 => + reflect_list_cps x0 + (fun ls : option (list (defaults.expr (type.base T))) => + match ls with + | Some ls0 => + base.try_make_transport_cps + (fun t0 : base.type => + defaults.expr (type.base t0)) T T + (UnderLets.UnderLets base.type ident var + (defaults.expr (type.base T))) + (fun + a : option + (defaults.expr (type.base T) -> + defaults.expr (type.base T)) => + match a with + | Some x' => + UnderLets.Base + (x' (nth_default default0 ls0 args)) + | None => + UnderLets.Base + (#(ident.List_nth_default)%expr @ x @ x0 @ + x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat + end) + | None => + UnderLets.Base + (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args + args0)%Z)%expr + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end + | None => UnderLets.Base (x + x0)%expr + end + | _ => UnderLets.Base (x + x0)%expr + end +| ident.Z_mul => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args * args0)%Z)%expr + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end + | None => UnderLets.Base (x * x0)%expr + end + | _ => UnderLets.Base (x * x0)%expr + end +| ident.Z_pow => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(args ^ args0)%expr + | None => + UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat + end +| ident.Z_sub => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args - args0)%Z)%expr + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end + | None => UnderLets.Base (x - x0)%expr + end + | _ => UnderLets.Base (x - x0)%expr + end +| ident.Z_opp => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => UnderLets.Base ##((- args)%Z)%expr + | None => UnderLets.Base (- x)%expr + end + | _ => UnderLets.Base (- x)%expr + end +| ident.Z_div => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args / args0)%Z)%expr + | None => UnderLets.Base (x / x0)%expr + end + | _ => UnderLets.Base (x / x0)%expr + end + | None => UnderLets.Base (x / x0)%expr + end + | _ => UnderLets.Base (x / x0)%expr + end +| ident.Z_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##((args mod args0)%Z)%expr + | None => UnderLets.Base (x mod x0)%expr + end + | _ => UnderLets.Base (x mod x0)%expr + end + | None => UnderLets.Base (x mod x0)%expr + end + | _ => UnderLets.Base (x mod x0)%expr + end +| ident.Z_log2 => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Z.log2 args)%expr + | None => UnderLets.Base (#(ident.Z_log2)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_log2)%expr @ x)%expr_pat + end +| ident.Z_log2_up => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Z.log2_up args)%expr + | None => UnderLets.Base (#(ident.Z_log2_up)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_log2_up)%expr @ x)%expr_pat + end +| ident.Z_eqb => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(args =? args0)%expr + | None => + UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat + end +| ident.Z_leb => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(args <=? args0)%expr + | None => + UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat + end +| ident.Z_geb => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(args >=? args0)%expr + | None => + UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_geb)%expr @ x @ x0)%expr_pat + end +| ident.Z_of_nat => + fun x : defaults.expr (type.base base.type.nat) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option nat) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun _ : Z => None + | base.type.bool => fun _ : bool => None + | base.type.nat => fun v0 : nat => Some v0 + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Z.of_nat args)%expr + | None => UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat + end +| ident.Z_to_nat => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Z.to_nat args)%expr + | None => UnderLets.Base (#(ident.Z_to_nat)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_to_nat)%expr @ x)%expr_pat + end +| ident.Z_shiftr => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(Z.shiftr args args0)%expr + | None => UnderLets.Base (x >> x0)%expr + end + | _ => UnderLets.Base (x >> x0)%expr + end + | None => UnderLets.Base (x >> x0)%expr + end + | _ => UnderLets.Base (x >> x0)%expr + end +| ident.Z_shiftl => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(Z.shiftl args args0)%expr + | None => UnderLets.Base (x << x0)%expr + end + | _ => UnderLets.Base (x << x0)%expr + end + | None => UnderLets.Base (x << x0)%expr + end + | _ => UnderLets.Base (x << x0)%expr + end +| ident.Z_land => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(Z.land args args0)%expr + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end + | None => UnderLets.Base (x &' x0)%expr + end + | _ => UnderLets.Base (x &' x0)%expr + end +| ident.Z_lor => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => UnderLets.Base ##(Z.lor args args0)%expr + | None => UnderLets.Base (x || x0)%expr + end + | _ => UnderLets.Base (x || x0)%expr + end + | None => UnderLets.Base (x || x0)%expr + end + | _ => UnderLets.Base (x || x0)%expr + end +| ident.Z_bneg => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => UnderLets.Base ##(Definitions.Z.bneg args)%expr + | None => UnderLets.Base (#(ident.Z_bneg)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_bneg)%expr @ x)%expr_pat + end +| ident.Z_lnot_modulo => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + UnderLets.Base + ##(Definitions.Z.lnot_modulo args args0)%expr + | None => + UnderLets.Base + (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat + end + | None => + UnderLets.Base (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_lnot_modulo)%expr @ x @ x0)%expr_pat + end +| ident.Z_mul_split => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + Definitions.Z.mul_split args args0 args1 in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add_get_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + Definitions.Z.add_get_carry_full args args0 + args1 in (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add_with_carry => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(Definitions.Z.add_with_carry args args0 + args1)%expr + | None => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add_with_get_carry => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + UnderLets.Base + (let + '(a, b) := + Definitions.Z.add_with_get_carry_full + args args0 args1 args2 in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end +| ident.Z_sub_get_borrow => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + Definitions.Z.sub_get_borrow_full args args0 + args1 in (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_sub_with_get_borrow => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + UnderLets.Base + (let + '(a, b) := + Definitions.Z.sub_with_get_borrow_full + args args0 args1 args2 in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ + x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ + x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ + x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end +| ident.Z_zselect => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(Definitions.Z.zselect args args0 args1)%expr + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_add_modulo => + fun x x0 x1 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(Definitions.Z.add_modulo args args0 args1)%expr + | None => + UnderLets.Base + (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat + end +| ident.Z_rshi => + fun x x0 x1 x2 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + UnderLets.Base + ##(Definitions.Z.rshi args args0 args1 + args2)%expr + | None => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ + x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | None => + UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat + end +| ident.Z_cc_m => + fun x x0 : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + match x0 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + UnderLets.Base ##(Definitions.Z.cc_m args args0)%expr + | None => + UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat + end +| ident.Z_cast range => + fun x : defaults.expr (type.base base.type.Z) => + match x with + | #(idc)%expr_pat => + match + match idc with + | @ident.Literal t0 v => + match t0 as t1 return (base.base_interp t1 -> option Z) with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args => + UnderLets.Base + ##(ident.cast ident.cast_outside_of_range range args)%expr + | None => UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat + end +| ident.Z_cast2 range => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + (let (r1, r2) := range in + fun '(x2, x3) => + (ident.cast ident.cast_outside_of_range r1 + x2, + ident.cast ident.cast_outside_of_range r2 x3)) + (args0, args1) in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | None => + UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | None => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat + end +| ident.fancy_add log2wordmax imm => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_add log2wordmax imm))) + (args0, args1) in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat + end +| ident.fancy_addc log2wordmax imm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + (let + '(a, b) := + ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_addc + log2wordmax imm))) + (args1, args2, args3) in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.fancy_addc log2wordmax + imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ + x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ + x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ + x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat + end +| ident.fancy_sub log2wordmax imm => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + (let + '(a, b) := + ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_sub log2wordmax imm))) + (args0, args1) in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat + end +| ident.fancy_subb log2wordmax imm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + (let + '(a, b) := + ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_subb + log2wordmax imm))) + (args1, args2, args3) in + (##(a)%expr, ##(b)%expr)%expr_pat) + | None => + UnderLets.Base + (#(ident.fancy_subb log2wordmax + imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ + x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ + x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ + x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat + end +| ident.fancy_mulll log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_mulll log2wordmax))) + (args0, args1)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat + end +| ident.fancy_mullh log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_mullh log2wordmax))) + (args0, args1)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat + end +| ident.fancy_mulhl log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_mulhl log2wordmax))) + (args0, args1)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat + end +| ident.fancy_mulhh log2wordmax => + fun x : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x0 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_mulhh log2wordmax))) + (args0, args1)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat + end +| ident.fancy_rshi log2wordmax x => + fun x0 : defaults.expr (type.base (base.type.Z * base.type.Z)%etype) => + match x0 with + | (#(idc) @ x2 @ x1)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x2 with + | #(idc0)%expr_pat => + match + match idc0 with + | @ident.Literal t1 v => + match + t1 as t2 return (base.base_interp t2 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args0 => + match x1 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_rshi log2wordmax x))) + (args0, args1)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end + | _ => + UnderLets.Base (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat + end +| ident.fancy_selc => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + ident.fancy_selc)) + (args1, args2, args3)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | None => + UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | None => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat + end +| ident.fancy_selm log2wordmax => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + (ident.fancy_selm + log2wordmax))) + (args1, args2, args3)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ + x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ + x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ + x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat + end +| ident.fancy_sell => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + ident.fancy_sell)) + (args1, args2, args3)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | None => + UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | None => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat + end +| ident.fancy_addm => + fun + x : defaults.expr + (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) => + match x with + | (#(idc) @ x1 @ x0)%expr_pat => + match + match idc with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x1 with + | (#(idc0) @ x3 @ x2)%expr_pat => + match + match idc0 with + | @ident.pair A B => Some (A, B) + | _ => None + end + with + | Some _ => + match x3 with + | #(idc1)%expr_pat => + match + match idc1 with + | @ident.Literal t2 v => + match + t2 as t3 + return (base.base_interp t3 -> option Z) + with + | base.type.unit => fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args1 => + match x2 with + | #(idc2)%expr_pat => + match + match idc2 with + | @ident.Literal t3 v => + match + t3 as t4 + return + (base.base_interp t4 -> option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => fun _ : nat => None + end v + | _ => None + end + with + | Some args2 => + match x0 with + | #(idc3)%expr_pat => + match + match idc3 with + | @ident.Literal t4 v => + match + t4 as t5 + return + (base.base_interp t5 -> + option Z) + with + | base.type.unit => + fun _ : unit => None + | base.type.Z => + fun v0 : Z => Some v0 + | base.type.bool => + fun _ : bool => None + | base.type.nat => + fun _ : nat => None + end v + | _ => None + end + with + | Some args3 => + UnderLets.Base + ##(ident.fancy.interp + (invert_Some + (ident.to_fancy + ident.fancy_addm)) + (args1, args2, args3)%core)%expr + | None => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | _ => + UnderLets.Base + (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | None => + UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | None => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat + end + | _ => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat + end +end + : Compile.value' true t diff --git a/src/Experiments/NewPipeline/rewrite_head.out b/src/Experiments/NewPipeline/rewrite_head.out deleted file mode 100644 index 600c4cb58..000000000 --- a/src/Experiments/NewPipeline/rewrite_head.out +++ /dev/null @@ -1,17274 +0,0 @@ -rewrite_head = -match idc in (ident t) return (Compile.value' true t) with -| @ident.Literal t v => - match - t as t0 - return - (base.base_interp t0 -> - UnderLets.UnderLets base.type ident var (expr (type.base t0))) - with - | base.type.unit => fun v0 : unit => UnderLets.Base ##(v0)%expr - | base.type.Z => fun v0 : Z => UnderLets.Base ##(v0)%expr - | base.type.bool => fun v0 : bool => UnderLets.Base ##(v0)%expr - | base.type.nat => fun v0 : nat => UnderLets.Base ##(v0)%expr - end v -| ident.Nat_succ => - fun x : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Nat.succ args)%expr - | None => UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_succ)%expr @ x)%expr_pat - end -| ident.Nat_pred => - fun x : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Nat.pred args)%expr - | None => UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_pred)%expr @ x)%expr_pat - end -| ident.Nat_max => - fun x x0 : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option nat) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##(Nat.max args args0)%expr - | None => - UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_max)%expr @ x @ x0)%expr_pat - end -| ident.Nat_mul => - fun x x0 : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option nat) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args * args0)%nat)%expr - | None => - UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_mul)%expr @ x @ x0)%expr_pat - end -| ident.Nat_add => - fun x x0 : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option nat) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args + args0)%nat)%expr - | None => - UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_add)%expr @ x @ x0)%expr_pat - end -| ident.Nat_sub => - fun x x0 : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option nat) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args - args0)%nat)%expr - | None => - UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Nat_sub)%expr @ x @ x0)%expr_pat - end -| @ident.nil t => UnderLets.Base []%expr_pat -| @ident.cons t => - fun (x : expr (type.base t)) (x0 : expr (type.base (base.type.list t))) - => UnderLets.Base (x :: x0)%expr_pat -| @ident.pair A B => - fun (x : expr (type.base A)) (x0 : expr (type.base B)) => - UnderLets.Base (x, x0)%expr_pat -| @ident.fst A B => - fun x : expr (type.base (A * B)%etype) => - match x with - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => - match - match idc with - | @ident.pair A0 B0 => Some (A0, B0) - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var (expr (type.base A))) - with - | type.base t2 => - fun v : expr (type.base t2) => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base A))) - with - | type.base t3 => - fun _ : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 A - (UnderLets.UnderLets base.type ident var - (expr (type.base A))) - (fun - a : option - (expr (type.base t2) -> expr (type.base A)) => - match a with - | Some x' => UnderLets.Base (x' v) - | None => - UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - end (Compile.reflect x0) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 => - UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - end (Compile.reflect x1) - | None => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ - _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App - _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ - s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | - @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - | _ => UnderLets.Base (#(ident.fst)%expr @ x)%expr_pat - end -| @ident.snd A B => - fun x : expr (type.base (A * B)%etype) => - match x with - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => - match - match idc with - | @ident.pair A0 B0 => Some (A0, B0) - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var (expr (type.base B))) - with - | type.base t2 => - fun _ : expr (type.base t2) => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base B))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t3 B - (UnderLets.UnderLets base.type ident var - (expr (type.base B))) - (fun - a : option - (expr (type.base t3) -> expr (type.base B)) => - match a with - | Some x' => UnderLets.Base (x' v0) - | None => - UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 => - UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - | None => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ - _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App - _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ - s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | - @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - | _ => UnderLets.Base (#(ident.snd)%expr @ x)%expr_pat - end -| @ident.prod_rect A B T => - fun - (x : expr (type.base A) -> - expr (type.base B) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x0 : expr (type.base (A * B)%etype)) => - match x0 with - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | - @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x2 : var (type.base A))(x3 : var (type.base B)), - UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0)%expr_pat - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x2) x1 => - match - match idc with - | @ident.pair A0 B0 => Some (A0, B0) - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - with - | type.base t2 => - fun v : expr (type.base t2) => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base T))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - Compile.castbe v - (UnderLets.UnderLets base.type ident var - (expr (type.base T))) - (fun x3 : option (expr (type.base A)) => - match x3 with - | Some x4 => - Compile.castbe v0 - (UnderLets.UnderLets base.type ident var - (expr (type.base T))) - (fun y : option (expr (type.base B)) => - match y with - | Some y0 => - (fv <-- (e <-- x x4 y0; - UnderLets.Base - {| - anyexpr_ty := T; - unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => - expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - T - (UnderLets.UnderLets base.type ident var - (expr (type.base T))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := - fv in - anyexpr_ty)) -> - expr (type.base T)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let - (anyexpr_ty, - _) := a0 in - anyexpr_ty))) := - fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x5 : var (type.base A)) - (x6 : var (type.base B)), - UnderLets.to_expr - (x ($x5) ($x6)))%expr @ x0)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x5 : var (type.base A))(x6 : - var - (type.base - B)), - UnderLets.to_expr (x ($x5) ($x6)))%expr @ - x0)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base B)), - UnderLets.to_expr (x ($x4) ($x5)))%expr @ x0)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x3 : var (type.base A))(x4 : var (type.base B)), - UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat - end (Compile.reflect x1) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x3 : var (type.base A))(x4 : var (type.base B)), - UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x3 : var (type.base A))(x4 : var (type.base B)), - UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ - _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x3 : var (type.base A))(x4 : var (type.base B)), - UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | - @expr.App _ _ _ s _ - (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x4 : var (type.base A))(x5 : var (type.base B)), - UnderLets.to_expr (x ($x4) ($x5)))%expr @ x0)%expr_pat - | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x3 : var (type.base A))(x4 : var (type.base B)), - UnderLets.to_expr (x ($x3) ($x4)))%expr @ x0)%expr_pat - | @expr.LetIn _ _ _ _ _ _ _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x2 : var (type.base A))(x3 : var (type.base B)), - UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ (x1 : var (type.base A))(x2 : var (type.base B)), - UnderLets.to_expr (x ($x1) ($x2)))%expr @ x0)%expr_pat - end -| @ident.bool_rect T => - fun - (x - x0 : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x1 : expr (type.base base.type.bool)) => - match x1 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option bool) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun v0 : bool => Some v0 - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - (fv <-- (e <-- (if args as b - return - (UnderLets.UnderLets base.type ident var - (expr (type.base (if b then T else T)))) - then x ##(tt)%expr - else x0 ##(tt)%expr); - UnderLets.Base - {| anyexpr_ty := if args then T else T; unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) T - (UnderLets.UnderLets base.type ident var (expr (type.base T))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base T)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in anyexpr_ty))) := - fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.bool_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.bool_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end - | ($_)%expr | @expr.Abs _ _ _ _ _ _ => - UnderLets.Base - (#(ident.bool_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.bool_rect)%expr @ - (λ x3 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x3)))%expr @ - (λ x3 : var (type.base base.type.unit), - UnderLets.to_expr (x0 ($x3)))%expr @ x1)%expr_pat - end -| @ident.nat_rect P => - fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base base.type.nat) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base base.type.nat)) => - match x1 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - Compile.castv x0 - (UnderLets.UnderLets base.type ident var (expr (type.base P))) - (fun - S_case : option - (expr (type.base base.type.nat) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var - (expr (type.base P))) => - match S_case with - | Some S_case0 => - (fv <-- (e <-- nat_rect - (fun _ : nat => - UnderLets.UnderLets base.type ident var - (expr (type.base P))) (x ##(tt)%expr) - (fun (n' : nat) - (rec : UnderLets.UnderLets base.type - ident var - (expr (type.base P))) => - rec0 <-- rec; - S_case0 ##(n')%expr rec0) args; - UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) P - (UnderLets.UnderLets base.type ident var - (expr (type.base P))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base P)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.nat_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base base.type.nat)) - (x3 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.nat_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base base.type.nat))(x3 : var - (type.base - P)), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.nat_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end - | ($_)%expr | @expr.Abs _ _ _ _ _ _ => - UnderLets.Base - (#(ident.nat_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base base.type.nat))(x3 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.nat_rect)%expr @ - (λ x3 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x3)))%expr @ - (λ (x3 : var (type.base base.type.nat))(x4 : var (type.base P)), - UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat - end -| @ident.list_rect A P => - fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base A) -> - expr (type.base (base.type.list A)) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base (base.type.list A))) => - Compile.castv x0 - (UnderLets.UnderLets base.type ident var (expr (type.base P))) - (fun - Pcons : option - (expr (type.base A) -> - expr (type.base (base.type.list A)) -> - expr (type.base P) -> - UnderLets.UnderLets base.type ident var - (expr (type.base P))) => - match Pcons with - | Some Pcons0 => - reflect_list_cps x1 - (fun ls : option (list (expr (type.base A))) => - match ls with - | Some ls0 => - (fv <-- (e <-- list_rect - (fun _ : list (expr (type.base A)) => - UnderLets.UnderLets base.type ident var - (expr (type.base P))) (x ##(tt)%expr) - (fun (x2 : expr (type.base A)) - (xs : list (expr (type.base A))) - (rec : UnderLets.UnderLets base.type - ident var (expr (type.base P))) - => - rec' <-- rec; - Pcons0 x2 (reify_list xs) rec') ls0; - UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) P - (UnderLets.UnderLets base.type ident var - (expr (type.base P))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base P)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.list_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base - (base.type.list - A))) - (x4 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ - x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.list_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base - (base.type.list A))) - (x4 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.list_rect)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base - (base.type.list A))) - (x4 : var (type.base P)), - UnderLets.to_expr (x0 ($x2) ($x3) ($x4)))%expr @ x1)%expr_pat - end) -| @ident.list_case A P => - fun - (x : expr (type.base base.type.unit) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x0 : expr (type.base A) -> - expr (type.base (base.type.list A)) -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - (x1 : expr (type.base (base.type.list A))) => - match x1 with - | #(idc)%expr_pat => - match match idc with - | @ident.nil t0 => Some t0 - | _ => None - end with - | Some _ => - (fv <-- (e <-- x ##(tt)%expr; - UnderLets.Base {| anyexpr_ty := P; unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) P - (UnderLets.UnderLets base.type ident var (expr (type.base P))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base P)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in anyexpr_ty))) := - fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base - (base.type.list - A))), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base - (base.type.list A))), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | - @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x3 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x3)))%expr @ - (λ (x3 : var (type.base A))(x4 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x3) x2 => - match match idc with - | @ident.cons t0 => Some t0 - | _ => None - end with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var (expr (type.base P))) - with - | type.base t2 => - fun v : expr (type.base t2) => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base P))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - Compile.castbe v - (UnderLets.UnderLets base.type ident var - (expr (type.base P))) - (fun x4 : option (expr (type.base A)) => - match x4 with - | Some x5 => - Compile.castbe v0 - (UnderLets.UnderLets base.type ident var - (expr (type.base P))) - (fun - xs : option - (expr (type.base (base.type.list A))) - => - match xs with - | Some xs0 => - (fv <-- (e <-- x0 x5 xs0; - UnderLets.Base - {| - anyexpr_ty := P; - unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => - expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - P - (UnderLets.UnderLets base.type ident var - (expr (type.base P))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := - fv in - anyexpr_ty)) -> - expr (type.base P)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let - (anyexpr_ty, - _) := a0 in - anyexpr_ty))) := - fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x6 : var - (type.base - base.type.unit), - UnderLets.to_expr (x ($x6)))%expr @ - (λ (x6 : var (type.base A)) - (x7 : var - (type.base - (base.type.list A))), - UnderLets.to_expr - (x0 ($x6) ($x7)))%expr @ x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x6 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x6)))%expr @ - (λ (x6 : var (type.base A))(x7 : - var - (type.base - (base.type.list - A))), - UnderLets.to_expr (x0 ($x6) ($x7)))%expr @ - x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x5 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x5)))%expr @ - (λ (x5 : var (type.base A))(x6 : var - (type.base - (base.type.list - A))), - UnderLets.to_expr (x0 ($x5) ($x6)))%expr @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x4 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x4)))%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base - (base.type.list - A))), - UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat - end (Compile.reflect x2) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x4 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x4)))%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base - (base.type.list A))), - UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x4 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x4)))%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base - (base.type.list A))), - UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ - _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x4 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x4)))%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | - @expr.App _ _ _ s _ - (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x5 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x5)))%expr @ - (λ (x5 : var (type.base A))(x6 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x5) ($x6)))%expr @ x1)%expr_pat - | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x4 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x4)))%expr @ - (λ (x4 : var (type.base A))(x5 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x4) ($x5)))%expr @ x1)%expr_pat - | @expr.LetIn _ _ _ _ _ _ _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x3 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x3)))%expr @ - (λ (x3 : var (type.base A))(x4 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x3) ($x4)))%expr @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.list_case)%expr @ - (λ x2 : var (type.base base.type.unit), - UnderLets.to_expr (x ($x2)))%expr @ - (λ (x2 : var (type.base A))(x3 : var - (type.base (base.type.list A))), - UnderLets.to_expr (x0 ($x2) ($x3)))%expr @ x1)%expr_pat - end -| @ident.List_length T => - fun x : expr (type.base (base.type.list T)) => - reflect_list_cps x - (fun xs : option (list (expr (type.base T))) => - match xs with - | Some xs0 => UnderLets.Base ##(length xs0)%expr - | None => UnderLets.Base (#(ident.List_length)%expr @ x)%expr_pat - end) -| ident.List_seq => - fun x x0 : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option nat) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (fold_right - (fun (x1 : expr (type.base base.type.nat)) - (xs : expr - (type.base (base.type.list base.type.nat))) - => (x1 :: xs)%expr_pat) []%expr_pat - (map (fun v : nat => ##(v)%expr) (seq args args0))) - | None => - UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.List_seq)%expr @ x @ x0)%expr_pat - end -| @ident.List_repeat A => - fun (x : expr (type.base A)) (x0 : expr (type.base base.type.nat)) => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - base.try_make_transport_cps - (fun A0 : base.type => expr (type.base (base.type.list A0))) A - A - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A)))) - (fun - a : option - (expr (type.base (base.type.list A)) -> - expr (type.base (base.type.list A))) => - match a with - | Some x' => UnderLets.Base (x' (reify_list (repeat x args))) - | None => - UnderLets.Base - (#(ident.List_repeat)%expr @ x @ x0)%expr_pat - end) - | None => - UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.List_repeat)%expr @ x @ x0)%expr_pat - end -| @ident.List_combine A B => - fun (x : expr (type.base (base.type.list A))) - (x0 : expr (type.base (base.type.list B))) => - reflect_list_cps x - (fun xs : option (list (expr (type.base A))) => - match xs with - | Some xs0 => - reflect_list_cps x0 - (fun ys : option (list (expr (type.base B))) => - match ys with - | Some ys0 => - (trA <-- base.try_make_transport_cps - (fun A0 : base.type => - expr (type.base (base.type.list (A0 * B)))) A A; - trB <-- base.try_make_transport_cps - (fun B0 : base.type => - expr (type.base (base.type.list (A * B0)))) B B; - return Some - (fun - v : expr (type.base (base.type.list (A * B))) - => trB (trA v)))%cps - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list (A * B))))) - (fun - a : option - (expr (type.base (base.type.list (A * B))) -> - expr (type.base (base.type.list (A * B)))) => - match a with - | Some x' => - UnderLets.Base - (x' - (reify_list - (map (fun '(x1, y) => (x1, y)%expr_pat) - (combine xs0 ys0)))) - | None => - UnderLets.Base - (#(ident.List_combine)%expr @ x @ x0)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_combine)%expr @ x @ x0)%expr_pat - end) - | None => - UnderLets.Base (#(ident.List_combine)%expr @ x @ x0)%expr_pat - end) -| @ident.List_map A B => - fun - (x : expr (type.base A) -> - UnderLets.UnderLets base.type ident var (expr (type.base B))) - (x0 : expr (type.base (base.type.list A))) => - Compile.castbe x0 - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (fun e : option (expr (type.base (base.type.list A))) => - match e with - | Some e0 => - reflect_list_cps e0 - (fun ls : option (list (expr (type.base A))) => - match ls with - | Some ls0 => - (fv <-- (e1 <-- list_rect - (fun _ : list (expr (type.base A)) => - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (UnderLets.Base []%expr_pat) - (fun (x1 : expr (type.base A)) - (_ : list (expr (type.base A))) - (rec : UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.list B)))) - => - rec' <-- rec; - fx <-- x x1; - UnderLets.Base (fx :: rec')%expr_pat) - ls0; - UnderLets.Base - {| - anyexpr_ty := base.type.list B; - unwrap := e1 |}); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - (base.type.list B) - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base (base.type.list B))) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.List_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.List_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) -| @ident.List_app A => - fun x x0 : expr (type.base (base.type.list A)) => - Compile.castbe x - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A)))) - (fun e : option (expr (type.base (base.type.list A))) => - match e with - | Some e0 => - reflect_list_cps e0 - (fun ls : option (list (expr (type.base A))) => - match ls with - | Some ls0 => - (fv <-- (e1 <-- list_rect - (fun _ : list (expr (type.base A)) => - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A)))) - (UnderLets.Base x0) - (fun (x1 : expr (type.base A)) - (_ : list (expr (type.base A))) - (rec : UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.list A)))) - => - rec' <-- rec; - UnderLets.Base (x1 :: rec')%expr_pat) - ls0; - UnderLets.Base - {| - anyexpr_ty := base.type.list A; - unwrap := e1 |}); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - (base.type.list A) - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A)))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base (base.type.list A))) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => UnderLets.Base (x ++ x0)%expr - end))%under_lets - | None => UnderLets.Base (x ++ x0)%expr - end) - | None => UnderLets.Base (x ++ x0)%expr - end) -| @ident.List_rev A => - fun x : expr (type.base (base.type.list A)) => - reflect_list_cps x - (fun xs : option (list (expr (type.base A))) => - match xs with - | Some xs0 => - base.try_make_transport_cps - (fun A0 : base.type => expr (type.base (base.type.list A0))) A A - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A)))) - (fun - a : option - (expr (type.base (base.type.list A)) -> - expr (type.base (base.type.list A))) => - match a with - | Some x' => UnderLets.Base (x' (reify_list (rev xs0))) - | None => UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat - end) - | None => UnderLets.Base (#(ident.List_rev)%expr @ x)%expr_pat - end) -| @ident.List_flat_map A B => - fun - (x : expr (type.base A) -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (x0 : expr (type.base (base.type.list A))) => - Compile.castbe x0 - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (fun e : option (expr (type.base (base.type.list A))) => - match e with - | Some e0 => - reflect_list_cps e0 - (fun ls : option (list (expr (type.base A))) => - match ls with - | Some ls0 => - (fv <-- (e1 <-- list_rect - (fun _ : list (expr (type.base A)) => - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (UnderLets.Base []%expr_pat) - (fun (x1 : expr (type.base A)) - (_ : list (expr (type.base A))) - (rec : UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.list B)))) - => - rec' <-- rec; - fx <-- x x1; - UnderLets.Base ($fx ++ rec')%expr) ls0; - UnderLets.Base - {| - anyexpr_ty := base.type.list B; - unwrap := e1 |}); - fv0 <-- do_again (let (anyexpr_ty, _) := fv in anyexpr_ty) - (let - (anyexpr_ty, unwrap) as a - return - (expr - (type.base - (let (anyexpr_ty, _) := a in - anyexpr_ty))) := fv in - unwrap); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - (base.type.list B) - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list B)))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base (base.type.list B))) => - match a with - | Some x' => UnderLets.Base (x' fv0) - | None => - UnderLets.Base - (#(ident.List_flat_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.List_flat_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_flat_map)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) -| @ident.List_partition A => - fun - (x : expr (type.base A) -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.bool))) - (x0 : expr (type.base (base.type.list A))) => - Compile.castbe x0 - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list A * base.type.list A)%etype))) - (fun e : option (expr (type.base (base.type.list A))) => - match e with - | Some e0 => - reflect_list_cps e0 - (fun ls : option (list (expr (type.base A))) => - match ls with - | Some ls0 => - (fv <-- (e1 <-- list_rect - (fun _ : list (expr (type.base A)) => - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.list A * - base.type.list A)%etype))) - (UnderLets.Base ([], [])%expr_pat) - (fun (x1 : expr (type.base A)) - (_ : list (expr (type.base A))) - (rec : UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.list A * - base.type.list A)%etype))) - => - rec' <-- rec; - fx <-- id x x1; - UnderLets.Base - (#(ident.prod_rect)%expr @ - (λ g - d : expr - (type.base - (base.type.list A)), - (#(ident.bool_rect)%expr @ - (λ _ : expr - (type.base base.type.unit), - ($x1 :: $g, $d)%expr_pat) @ - (λ _ : expr - (type.base base.type.unit), - ($g, $x1 :: $d)%expr_pat) @ $fx)%expr_pat)%expr @ - rec')%expr_pat) ls0; - UnderLets.Base - {| - anyexpr_ty := (base.type.list A * - base.type.list A)%etype; - unwrap := e1 |}); - fv0 <-- do_again (let (anyexpr_ty, _) := fv in anyexpr_ty) - (let - (anyexpr_ty, unwrap) as a - return - (expr - (type.base - (let (anyexpr_ty, _) := a in - anyexpr_ty))) := fv in - unwrap); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - (base.type.list A * base.type.list A) - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.list A * base.type.list A)%etype))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr - (type.base - (base.type.list A * base.type.list A)%etype)) - => - match a with - | Some x' => UnderLets.Base (x' fv0) - | None => - UnderLets.Base - (#(ident.List_partition)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.List_partition)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_partition)%expr @ - (λ x1 : var (type.base A), - UnderLets.to_expr (x ($x1)))%expr @ x0)%expr_pat - end) -| @ident.List_fold_right A B => - fun - (x : expr (type.base B) -> - expr (type.base A) -> - UnderLets.UnderLets base.type ident var (expr (type.base A))) - (x0 : expr (type.base A)) (x1 : expr (type.base (base.type.list B))) => - Compile.castv x - (UnderLets.UnderLets base.type ident var (expr (type.base A))) - (fun - f : option - (expr (type.base B) -> - expr (type.base A) -> - UnderLets.UnderLets base.type ident var (expr (type.base A))) - => - match f with - | Some f0 => - reflect_list_cps x1 - (fun ls : option (list (expr (type.base B))) => - match ls with - | Some ls0 => - (fv <-- (e <-- list_rect - (fun _ : list (expr (type.base B)) => - UnderLets.UnderLets base.type ident var - (expr (type.base A))) - (UnderLets.Base x0) - (fun (x2 : expr (type.base B)) - (_ : list (expr (type.base B))) - (rec : UnderLets.UnderLets base.type - ident var (expr (type.base A))) - => rec' <-- rec; - f0 x2 rec') ls0; - UnderLets.Base {| anyexpr_ty := A; unwrap := e |}); - base.try_make_transport_cps - (fun t : base.type => expr (type.base t)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) A - (UnderLets.UnderLets base.type ident var - (expr (type.base A))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in anyexpr_ty)) -> - expr (type.base A)) => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.List_fold_right)%expr @ - (λ (x2 : var (type.base B))(x3 : var - (type.base A)), - UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ - x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.List_fold_right)%expr @ - (λ (x2 : var (type.base B))(x3 : var (type.base A)), - UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_fold_right)%expr @ - (λ (x2 : var (type.base B))(x3 : var (type.base A)), - UnderLets.to_expr (x ($x2) ($x3)))%expr @ x0 @ x1)%expr_pat - end) -| @ident.List_update_nth T => - fun (x : expr (type.base base.type.nat)) - (x0 : expr (type.base T) -> - UnderLets.UnderLets base.type ident var (expr (type.base T))) - (x1 : expr (type.base (base.type.list T))) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - Compile.castv x0 - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list T)))) - (fun - f : option - (expr (type.base T) -> - UnderLets.UnderLets base.type ident var - (expr (type.base T))) => - match f with - | Some f0 => - reflect_list_cps x1 - (fun ls : option (list (expr (type.base T))) => - match ls with - | Some ls0 => - (fv <-- (e <-- (retv <---- update_nth args - (fun - x2 : UnderLets.UnderLets - base.type - ident var - (expr - (type.base - T)) => - x3 <-- x2; - f0 x3) - (map UnderLets.Base - ls0); - UnderLets.Base (reify_list retv)); - UnderLets.Base - {| - anyexpr_ty := base.type.list T; - unwrap := e |}); - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - (let (anyexpr_ty, _) := fv in anyexpr_ty) - (base.type.list T) - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.list T)))) - (fun - a : option - (expr - (type.base - (let (anyexpr_ty, _) := fv in - anyexpr_ty)) -> - expr (type.base (base.type.list T))) - => - match a with - | Some x' => - UnderLets.Base - (x' - (let - (anyexpr_ty, unwrap) as a0 - return - (expr - (type.base - (let (anyexpr_ty, _) := - a0 in - anyexpr_ty))) := fv in - unwrap)) - | None => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x2 : var (type.base T), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end))%under_lets - | None => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x2 : var (type.base T), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x2 : var (type.base T), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x2 : var (type.base T), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - end - | ($_)%expr | @expr.Abs _ _ _ _ _ _ => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x2 : var (type.base T), - UnderLets.to_expr (x0 ($x2)))%expr @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.List_update_nth)%expr @ x @ - (λ x3 : var (type.base T), - UnderLets.to_expr (x0 ($x3)))%expr @ x1)%expr_pat - end -| @ident.List_nth_default T => - fun (x : expr (type.base T)) (x0 : expr (type.base (base.type.list T))) - (x1 : expr (type.base base.type.nat)) => - match x1 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => - Compile.castbe x - (UnderLets.UnderLets base.type ident var (expr (type.base T))) - (fun default : option (expr (type.base T)) => - match default with - | Some default0 => - reflect_list_cps x0 - (fun ls : option (list (expr (type.base T))) => - match ls with - | Some ls0 => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) T T - (UnderLets.UnderLets base.type ident var - (expr (type.base T))) - (fun - a : option - (expr (type.base T) -> - expr (type.base T)) => - match a with - | Some x' => - UnderLets.Base - (x' (nth_default default0 ls0 args)) - | None => - UnderLets.Base - (#(ident.List_nth_default)%expr @ x @ x0 @ - x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat - end) - | None => - UnderLets.Base - (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.List_nth_default)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_add => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args + args0)%Z)%expr - | None => - if args =? 0 - then UnderLets.Base x0 - else UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ f x1 => - if args =? 0 - then UnderLets.Base x0 - else - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args >? 0 - then - UnderLets.Base (##(args) - x' v)%expr - else - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - if args - UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - with - | type.base t4 => - fun - v1 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - (fun - a1 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a1 with - | Some x'1 => - UnderLets.Base - (x - x'1 v1)%expr - | None => - UnderLets.Base - (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' - false s0 -> - Compile.value' - true d0 => - UnderLets.Base - (x + x0)%expr - end (Compile.reflect x1) - | None => - UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | _ => - if args =? 0 - then UnderLets.Base x0 - else UnderLets.Base (x + x0)%expr - end - | None => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else UnderLets.Base (x + x0)%expr - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x + x0)%expr - | _ => UnderLets.Base (x + x0)%expr - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else UnderLets.Base (x + x0)%expr - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v0)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x + x0)%expr - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else UnderLets.Base (x + x0)%expr - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x + x0)%expr - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ f x1 => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args >? 0 - then - UnderLets.Base (##(args) - x' v)%expr - else - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - if args - UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - with - | type.base t4 => - fun - v1 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - (fun - a1 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a1 with - | Some x'1 => - UnderLets.Base - (x0 - x'1 v1)%expr - | None => - UnderLets.Base - (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' - false s0 -> - Compile.value' - true d0 => - UnderLets.Base - (x + x0)%expr - end (Compile.reflect x1) - | None => - UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | None => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - end - | ($_)%expr => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v0)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (- (x' v + x'0 v0))%expr - | None => - UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v0)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - end - | None => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v0)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 - _ (_ @ _)%expr_pat _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x0 - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x + x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x + x0)%expr - end - | _ => UnderLets.Base (x + x0)%expr - end - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else UnderLets.Base (x + x0)%expr - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x - x' v)%expr - | None => UnderLets.Base (x + x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x + x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x + x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x + x0)%expr - | _ => UnderLets.Base (x + x0)%expr - end - end -| ident.Z_mul => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args * args0)%Z)%expr - | None => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x0 - else - if args =? -1 - then UnderLets.Base (- x0)%expr - else - if args - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x0 - else - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? -1 - then UnderLets.Base (x' v) - else - if args =? -1 - then UnderLets.Base (- x0)%expr - else - if args - UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (- (x * x'0 v0))%expr - | None => - UnderLets.Base - (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => - if args =? -1 - then UnderLets.Base (- x0)%expr - else - if args - if args =? -1 - then UnderLets.Base (- x0)%expr - else - if args - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x0 - else - if args =? -1 - then UnderLets.Base (- x0)%expr - else - if args - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x - else - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x - else - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x - else - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ f x1 => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x - else - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? -1 - then UnderLets.Base (x' v) - else - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args - UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (- (x'0 v0 * x0))%expr - | None => - UnderLets.Base - (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - end - | ($_)%expr => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v0 * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v * x'0 v0)%expr - | None => - UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - end - | None => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v0 * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 - _ (_ @ _)%expr_pat _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v * x0))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x * x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x * x0)%expr - end - | _ => UnderLets.Base (x * x0)%expr - end - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base ##(0)%expr - else - if args =? 1 - then UnderLets.Base x - else - if args =? -1 - then UnderLets.Base (- x)%expr - else - if args UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x * x' v))%expr - | None => UnderLets.Base (x * x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x * x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x * x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x * x0)%expr - | _ => UnderLets.Base (x * x0)%expr - end - end -| ident.Z_pow => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##(args ^ args0)%expr - | None => - UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_pow)%expr @ x @ x0)%expr_pat - end -| ident.Z_sub => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args - args0)%Z)%expr - | None => - if args =? 0 - then UnderLets.Base (- x0)%expr - else - if args - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args =? 0 - then UnderLets.Base (x' v) - else - if args =? 0 - then UnderLets.Base (- x0)%expr - else - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - if args >? 0 - then - UnderLets.Base - (##(args) + x'0 v0)%expr - else - match - s as t4 - return - (Compile.value' false t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base base.type.Z))) - with - | type.base t4 => - fun v1 : expr (type.base t4) - => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t4 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - (fun - a1 : option - (expr - (type.base t4) -> - expr - (type.base - base.type.Z)) - => - match a1 with - | Some x'1 => - if args - UnderLets.UnderLets - base.type - ident var - (expr - (type.base - base.type.Z))) - with - | type.base t5 => - fun - v2 : - expr - (type.base - t5) => - base.try_make_transport_cps - (fun - t1 : base.type - => - expr - (type.base - t1)) t5 - base.type.Z - (UnderLets.UnderLets - base.type - ident var - (expr - (type.base - base.type.Z))) - (fun - a2 : - option - (expr - (type.base - t5) -> - expr - (type.base - base.type.Z)) - => - match - a2 - with - | Some - x'2 => - UnderLets.Base - (x + - x'2 v2)%expr - | None => - UnderLets.Base - (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' - false s0 -> - Compile.value' - true d0 - => - UnderLets.Base - (x - x0)%expr - end - (Compile.reflect - x1) - | None => - UnderLets.Base - (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false - s0 -> - Compile.value' true d0 - => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => - UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => - if args =? 0 - then UnderLets.Base (- x0)%expr - else - if args - if args =? 0 - then UnderLets.Base (- x0)%expr - else - if args - if args =? 0 - then UnderLets.Base (- x0)%expr - else - if args - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - if args UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => UnderLets.Base (x - x0)%expr - | _ => UnderLets.Base (x - x0)%expr - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - if args UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v0)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x - x0)%expr - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - if args UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x - x0)%expr - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ f x1 => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args >? 0 - then - UnderLets.Base - (- (x' v + ##((- args)%Z)))%expr - else - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - if args - UnderLets.UnderLets - base.type ident var - (expr - (type.base - base.type.Z))) - with - | type.base t4 => - fun - v1 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t1 : base.type - => - expr (type.base t1)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident - var - (expr - (type.base - base.type.Z))) - (fun - a1 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a1 with - | Some x'1 => - UnderLets.Base - (- - (x'1 v1 + x0))%expr - | None => - UnderLets.Base - (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' - false s0 -> - Compile.value' - true d0 => - UnderLets.Base - (x - x0)%expr - end (Compile.reflect x1) - | None => - UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => - if args - if args - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - end - | ($_)%expr => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v0 + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.Abs _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var (expr (type.base base.type.Z))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr (type.base base.type.Z))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x'0 v0 - x' v)%expr - | None => - UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v0)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - end - | None => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v0 + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 - _ (_ @ _)%expr_pat _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f with - | #(idc)%expr_pat => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (- (x' v + x0))%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base (x - x0)%expr - end (Compile.reflect x1) - | None => UnderLets.Base (x - x0)%expr - end - | _ => UnderLets.Base (x - x0)%expr - end - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 0 - then UnderLets.Base x - else - if args UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x + x' v)%expr - | None => UnderLets.Base (x - x0)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 - => UnderLets.Base (x - x0)%expr - end (Compile.reflect x2) - | None => UnderLets.Base (x - x0)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (x - x0)%expr - | _ => UnderLets.Base (x - x0)%expr - end - end -| ident.Z_opp => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => UnderLets.Base ##((- args)%Z)%expr - | None => UnderLets.Base (- x)%expr - end - | @expr.App _ _ _ s _ #(idc)%expr_pat x0 => - match match idc with - | ident.Z_opp => Some tt - | _ => None - end with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base base.type.Z))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => UnderLets.Base (x' v) - | None => UnderLets.Base (- x)%expr - end) - | (s0 -> d0)%ptype => - fun _ : Compile.value' false s0 -> Compile.value' true d0 => - UnderLets.Base (- x)%expr - end (Compile.reflect x0) - | None => UnderLets.Base (- x)%expr - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (- x)%expr - | _ => UnderLets.Base (- x)%expr - end -| ident.Z_div => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args / args0)%Z)%expr - | None => UnderLets.Base (x / x0)%expr - end - | _ => UnderLets.Base (x / x0)%expr - end - | None => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then UnderLets.Base (x >> Z.log2 args)%expr - else UnderLets.Base (x / x0)%expr - | None => UnderLets.Base (x / x0)%expr - end - | _ => UnderLets.Base (x / x0)%expr - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then UnderLets.Base (x >> Z.log2 args)%expr - else UnderLets.Base (x / x0)%expr - | None => UnderLets.Base (x / x0)%expr - end - | _ => UnderLets.Base (x / x0)%expr - end - | _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then UnderLets.Base (x >> Z.log2 args)%expr - else UnderLets.Base (x / x0)%expr - | None => UnderLets.Base (x / x0)%expr - end - | _ => UnderLets.Base (x / x0)%expr - end - end -| ident.Z_modulo => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##((args mod args0)%Z)%expr - | None => UnderLets.Base (x mod x0)%expr - end - | _ => UnderLets.Base (x mod x0)%expr - end - | None => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then - UnderLets.Base - (#(ident.Z_land (args - 1))%expr @ x)%expr_pat - else UnderLets.Base (x mod x0)%expr - | None => UnderLets.Base (x mod x0)%expr - end - | _ => UnderLets.Base (x mod x0)%expr - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then - UnderLets.Base - (#(ident.Z_land (args - 1))%expr @ x)%expr_pat - else UnderLets.Base (x mod x0)%expr - | None => UnderLets.Base (x mod x0)%expr - end - | _ => UnderLets.Base (x mod x0)%expr - end - | _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args =? 2 ^ Z.log2 args - then - UnderLets.Base - (#(ident.Z_land (args - 1))%expr @ x)%expr_pat - else UnderLets.Base (x mod x0)%expr - | None => UnderLets.Base (x mod x0)%expr - end - | _ => UnderLets.Base (x mod x0)%expr - end - end -| ident.Z_eqb => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##(args =? args0)%expr - | None => - UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_eqb)%expr @ x @ x0)%expr_pat - end -| ident.Z_leb => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => UnderLets.Base ##(args <=? args0)%expr - | None => - UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_leb)%expr @ x @ x0)%expr_pat - end -| ident.Z_of_nat => - fun x : expr (type.base base.type.nat) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option nat) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun _ : Z => None - | base.type.bool => fun _ : bool => None - | base.type.nat => fun v0 : nat => Some v0 - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Z.of_nat args)%expr - | None => UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_of_nat)%expr @ x)%expr_pat - end -| ident.Z_shiftr offset => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Z.shiftr args offset)%expr - | None => UnderLets.Base (x >> offset)%expr - end - | _ => UnderLets.Base (x >> offset)%expr - end -| ident.Z_shiftl offset => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Z.shiftl args offset)%expr - | None => UnderLets.Base (x << offset)%expr - end - | _ => UnderLets.Base (x << offset)%expr - end -| ident.Z_land mask => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Z.land args mask)%expr - | None => UnderLets.Base (#(ident.Z_land mask)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_land mask)%expr @ x)%expr_pat - end -| ident.Z_mul_split => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.mul_split args args0 args1 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - if args0 =? 0 - then - UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat - else - if args0 =? 1 - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - if args0 =? -1 - then - UnderLets.Base - ((- x1)%expr, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - if args0 =? 0 - then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat - else - if args0 =? 1 - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - if args0 =? -1 - then - UnderLets.Base ((- x1)%expr, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | None => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then - UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat - else - if args0 =? 1 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - if args0 =? -1 - then - UnderLets.Base - ((- x0)%expr, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ - x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ x1)%expr_pat - end - end - | ($_)%expr => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat - else - if args0 =? 1 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - if args0 =? -1 - then - UnderLets.Base ((- x0)%expr, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ x1)%expr_pat - end - | _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (##(0)%expr, ##(0)%expr)%expr_pat - else - if args0 =? 1 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - if args0 =? -1 - then - UnderLets.Base ((- x0)%expr, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_mul_split_concrete args)%expr @ x0 @ x1)%expr_pat - end - end - | None => - UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_mul_split)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_mul_split_concrete s => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (let - '(a, b) := Definitions.Z.mul_split s args args0 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_mul_split_concrete s)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_mul_split_concrete s)%expr @ x @ x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_mul_split_concrete s)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_mul_split_concrete s)%expr @ x @ x0)%expr_pat - end -| ident.Z_add_get_carry => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.add_get_carry_full args args0 - args1 in (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - if args0 =? 0 - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s _ f x2 => - if args0 =? 0 - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - if args0 =? 0 - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | None => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s _ #(idc1)%expr_pat x2 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - end - | ($_)%expr => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete args)%expr @ - x0 @ x' v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete args)%expr @ - x0 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s _ f x2 => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | None => - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - end - | ($_)%expr => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ x' v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s0 _ f0 x3 => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - match f0 with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - end - | ($_)%expr => - match f0 with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ x' v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f0 with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - match f0 with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x0 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete - args)%expr @ x1 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ - x0 @ x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - if args0 =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s _ #(idc0)%expr_pat x3 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete args)%expr @ - x0 @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s0 -> d0)%ptype => - fun - _ : Compile.value' false s0 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s _ ($_)%expr _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ x0 @ x1)%expr_pat - end - end - | None => - UnderLets.Base - (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base (#(ident.Z_add_get_carry)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_add_get_carry_concrete s => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.add_get_carry_full s args args0 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun - v : var - (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | ($_)%expr => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun - v0 : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ - x @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun - v : var - (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun - v0 : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ - _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x0, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | None => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun - v : var - (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x1 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ - x @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | ($_)%expr => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun - v0 : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x1 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x1 => - match match idc with - | ident.Z_opp => Some tt - | _ => None - end with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x0 @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x1) - | None => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun - v : var - (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x2 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ - x @ x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ - x @ x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t1 v0 => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun - v0 : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s2 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s3 -> d2)%ptype => - fun _ : Compile.value' false s3 -> Compile.value' true d2 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc)%expr_pat x3 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s1 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s2 -> d1)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x0 with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match - t0 as t1 return (base.base_interp t1 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - if args <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - ##((- args)%Z)%expr)%expr_pat - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - else - if args =? 0 - then UnderLets.Base (x, ##(0)%expr)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match - match idc with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - UnderLets.UnderLet - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ - x' v)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ - x0)%expr_pat - end) - | (s1 -> d0)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d0 - => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat - _ | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_get_carry_concrete s)%expr @ x @ x0)%expr_pat - end - end -| ident.Z_add_with_carry => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(Definitions.Z.add_with_carry args args0 - args1)%expr - | None => - if args =? 0 - then UnderLets.Base (x0 + x1)%expr - else - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - if args =? 0 - then UnderLets.Base (x0 + x1)%expr - else - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - if args =? 0 - then UnderLets.Base (x0 + x1)%expr - else - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - if args =? 0 - then UnderLets.Base (x0 + x1)%expr - else - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_carry)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_add_with_get_carry => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.add_with_get_carry_full - args args0 args1 args2 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base (x2, ##(0)%expr)%expr_pat - else - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - args)%expr @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - if (args0 =? 0) && (args1 =? 0) - then UnderLets.Base (x2, ##(0)%expr)%expr_pat - else - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | None => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete - args)%expr @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - end - | ($_)%expr => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t3 v0 => - match - t3 as t4 - return (base.base_interp t4 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then UnderLets.Base (x1, ##(0)%expr)%expr_pat - else - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - if args0 =? 0 - then - UnderLets.Base - (#(ident.Z_add_get_carry_concrete args)%expr @ - x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - end - | None => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - end - | ($_)%expr => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t3 v0 => - match - t3 as t4 - return (base.base_interp t4 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ x0 @ - x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s _ f x3 => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x4 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match f with - | #(idc2)%expr_pat => - match - match idc2 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a with - | Some x' => - match - s0 as t4 - return - (Compile.value' false - t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t4 => - fun - v0 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t5 : base.type - => - expr (type.base t5)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident - var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : - var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (# - (ident.fst)%expr @ - ($v1)%expr, - (- - (# - (ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ - x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' - false s1 -> - Compile.value' - true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ - s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 - _ (_ @ _)%expr_pat _ | @expr.App _ _ _ s0 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s0 _ #(idc2)%expr_pat x4 => - match - match idc2 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a with - | Some x' => - match - s0 as t4 - return - (Compile.value' false - t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t4 => - fun - v0 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t5 : base.type - => - expr (type.base t5)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident - var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : - var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (# - (ident.fst)%expr @ - ($v1)%expr, - (- - (# - (ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ - x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' - false s1 -> - Compile.value' - true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | - @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ - s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - end - | ($_)%expr => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x4 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s0 as t4 - return - (Compile.value' false t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t4 => - fun - v1 : expr (type.base t4) - => - base.try_make_transport_cps - (fun t5 : base.type => - expr (type.base t5)) t4 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v0 @ x1 @ - x'0 v1)%expr_pat - (fun - v2 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v2)%expr, - (- - (#(ident.snd)%expr @ - $v2)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false - s1 -> - Compile.value' true - d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ - _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x4 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun - v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false - s2 -> - Compile.value' true - d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ - _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc0)%expr_pat x4 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) - => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x2 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 - => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ x @ - x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - match f with - | #(idc1)%expr_pat => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s1 _ #(idc2)%expr_pat x5 => - match - match idc2 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a with - | Some x' => - match - s1 as t4 - return - (Compile.value' false - t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t4 => - fun - v0 : expr - (type.base t4) - => - base.try_make_transport_cps - (fun t5 : base.type - => - expr (type.base t5)) - t4 base.type.Z - (UnderLets.UnderLets - base.type ident - var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : - var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (# - (ident.fst)%expr @ - ($v1)%expr, - (- - (# - (ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ - x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' - false s2 -> - Compile.value' - true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | - @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ - s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - end - | @expr.App _ _ _ s0 _ ($_)%expr _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x5 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s1 as t4 - return - (Compile.value' false t4 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t4 => - fun - v1 : expr (type.base t4) - => - base.try_make_transport_cps - (fun t5 : base.type => - expr (type.base t5)) t4 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t4) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v0 @ x1 @ - x'0 v1)%expr_pat - (fun - v2 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v2)%expr, - (- - (#(ident.snd)%expr @ - $v2)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false - s2 -> - Compile.value' true - d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ - _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s2 _ #(idc1)%expr_pat x5 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun - v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s3 -> d3)%ptype => - fun - _ : Compile.value' false - s3 -> - Compile.value' true - d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s3 -> d3)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ - _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s2 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s2 _ #(idc1)%expr_pat x6 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun - v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s3 -> d3)%ptype => - fun - _ : Compile.value' false - s3 -> - Compile.value' true - d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x6) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s3 -> d3)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ - _ _ s2 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s2 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s2 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x6 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun - v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false - s2 -> - Compile.value' true - d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x6) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ - _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s1 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match f with - | #(idc0)%expr_pat => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match x2 with - | @expr.App _ _ _ s0 _ #(idc1)%expr_pat x5 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => - expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr - (type.base base.type.Z)) - => - match a with - | Some x' => - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun - v0 : expr (type.base t3) - => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets - base.type ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr - (type.base - t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ - x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false - s1 -> - Compile.value' true - d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ - x @ x0 @ x1 @ x2)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ - _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App - _ _ _ s0 _ (_ @ _)%expr_pat _ | @expr.App _ _ _ - s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - end - | _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - if (args0 =? 0) && (args1 =? 0) - then - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete args)%expr @ x0 @ - x1 @ x2)%expr_pat - end - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end -| ident.Z_add_with_get_carry_concrete s => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.add_with_get_carry_full s args - args0 args1 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s0 _ #(idc)%expr_pat x2 => - match match idc with - | ident.Z_opp => Some tt - | _ => None - end with - | Some _ => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - match - s0 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) - => - match a0 with - | Some x'0 => - if args1 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ - x'0 v0 @ x0 @ - ##((- args1)%Z)%expr)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.Abs _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x3 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - end - | @expr.App _ _ _ s1 _ ($_)%expr _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ | - @expr.App _ _ _ s1 _ (_ @ _)%expr_pat _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - end - | None => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc1)%expr_pat x3 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - | ($_)%expr => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x3 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x0 @ - x'0 v1)%expr_pat - (fun - v2 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v2)%expr, - (- - (#(ident.snd)%expr @ $v2)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.Abs _ _ _ _ _ _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc0)%expr_pat x3 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x3 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x1 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x3) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc1)%expr_pat x4 => - match - match idc1 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ - $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ - x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - end - | @expr.App _ _ _ s1 _ ($_)%expr _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc0)%expr_pat x4 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v0 @ x0 @ - x'0 v1)%expr_pat - (fun - v2 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v2)%expr, - (- - (#(ident.snd)%expr @ $v2)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s1 _ (@expr.Abs _ _ _ _ _ _) _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s3 _ #(idc0)%expr_pat x4 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s3 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s4 -> d3)%ptype => - fun - _ : Compile.value' false s4 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s4 -> d3)%ptype => - fun - _ : Compile.value' false s4 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s3 _ ($_)%expr _ | @expr.App _ _ _ s3 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s3 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s3 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s1 _ (_ @ _)%expr_pat _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s3 _ #(idc0)%expr_pat x5 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s3 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s4 -> d3)%ptype => - fun - _ : Compile.value' false s4 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s4 -> d3)%ptype => - fun - _ : Compile.value' false s4 -> - Compile.value' true d3 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s3 _ ($_)%expr _ | @expr.App _ _ _ s3 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s3 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s3 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.App _ _ _ s1 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ #(idc0)%expr_pat x5 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s2 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x5) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s3 -> d2)%ptype => - fun - _ : Compile.value' false s3 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s2 _ ($_)%expr _ | @expr.App _ _ _ s2 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s2 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s2 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | @expr.LetIn _ _ _ _ _ _ _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - if args0 <=? 0 - then - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - ##((- args0)%Z)%expr)%expr_pat - (fun - v0 : var - (type.base - (base.type.Z * base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- - (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - else - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s1 -> d0)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d0 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ #(idc0)%expr_pat x4 => - match - match idc0 with - | ident.Z_opp => Some tt - | _ => None - end - with - | Some _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s1 as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.UnderLet - (#(ident.Z_sub_with_get_borrow_concrete - s)%expr @ x' v @ x0 @ - x'0 v0)%expr_pat - (fun - v1 : var - (type.base - (base.type.Z * - base.type.Z)%etype) - => - UnderLets.Base - (#(ident.fst)%expr @ - ($v1)%expr, - (- - (#(ident.snd)%expr @ $v1)%expr_pat)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete - s)%expr @ x @ x0 @ x1)%expr_pat - end (Compile.reflect x4) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end) - | (s2 -> d1)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end (Compile.reflect x2) - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s1 _ ($_)%expr _ | @expr.App _ _ _ s1 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s1 _ - (_ @ _)%expr_pat _ | @expr.App _ _ _ s1 _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - end - | None => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | @expr.App _ _ _ s0 _ ($_)%expr _ | @expr.App _ _ _ s0 _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s0 _ (_ @ _)%expr_pat _ | - @expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - | _ => - UnderLets.Base - (#(ident.Z_add_with_get_carry_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_sub_get_borrow => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.sub_get_borrow_full args args0 - args1 in (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete args)%expr @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete args)%expr @ x0 @ - x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete args)%expr @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete args)%expr @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_get_borrow)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_sub_get_borrow_concrete s => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.sub_get_borrow_full s args args0 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_get_borrow_concrete s)%expr @ x @ x0)%expr_pat - end -| ident.Z_sub_with_get_borrow => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.sub_with_get_borrow_full - args args0 args1 args2 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete - args)%expr @ x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete args)%expr @ - x0 @ x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete args)%expr @ x0 @ - x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete args)%expr @ x0 @ - x1 @ x2)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end -| ident.Z_sub_with_get_borrow_concrete s => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - Definitions.Z.sub_with_get_borrow_full s args - args0 args1 in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ - x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ - x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ - x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_sub_with_get_borrow_concrete s)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_zselect => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(Definitions.Z.zselect args args0 args1)%expr - | None => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_zselect)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_add_modulo => - fun x x0 x1 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(Definitions.Z.add_modulo args args0 args1)%expr - | None => - UnderLets.Base - (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_add_modulo)%expr @ x @ x0 @ x1)%expr_pat - end -| ident.Z_rshi => - fun x x0 x1 x2 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - UnderLets.Base - ##(Definitions.Z.rshi args args0 args1 - args2)%expr - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ - x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | None => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args1)%expr @ - x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ - x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - end - | ($_)%expr => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t3 v0 => - match - t3 as t4 - return (base.base_interp t4 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args1 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args1)%expr @ - x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args1)%expr @ - x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - end - | None => - match x2 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args0)%expr @ x0 @ - x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - end - | ($_)%expr => - match x2 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t2 v0 => - match - t2 as t3 return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v1 : Z => Some v1 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v0 - | _ => None - end - with - | Some args0 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args0)%expr @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - match x2 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - (#(ident.Z_rshi_concrete args args0)%expr @ x0 @ x1)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - end - | None => - UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_rshi)%expr @ x @ x0 @ x1 @ x2)%expr_pat - end -| ident.Z_rshi_concrete s offset => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base - ##(Definitions.Z.rshi s args args0 offset)%expr - | None => - UnderLets.Base - (#(ident.Z_rshi_concrete s offset)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi_concrete s offset)%expr @ x @ x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.Z_rshi_concrete s offset)%expr @ x @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_rshi_concrete s offset)%expr @ x @ x0)%expr_pat - end -| ident.Z_cc_m => - fun x x0 : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - match x0 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - UnderLets.Base ##(Definitions.Z.cc_m args args0)%expr - | None => - UnderLets.Base - (#(ident.Z_cc_m_concrete args)%expr @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.Z_cc_m_concrete args)%expr @ x0)%expr_pat - end - | None => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_cc_m)%expr @ x @ x0)%expr_pat - end -| ident.Z_cc_m_concrete s => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => UnderLets.Base ##(Definitions.Z.cc_m s args)%expr - | None => - UnderLets.Base (#(ident.Z_cc_m_concrete s)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_cc_m_concrete s)%expr @ x)%expr_pat - end -| ident.Z_neg_snd => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | ($_)%expr => - UnderLets.UnderLet x - (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | @expr.App _ _ _ s _ ($_)%expr _ => - UnderLets.UnderLet x - (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (##(args0)%expr, ##((- args1)%Z)%expr)%expr_pat - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ - x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v0, (- x'0 v1)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v0, (- x'0 v1)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => UnderLets.Base (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - UnderLets.Base - (x' v, (- x'0 v0)%expr)%expr_pat - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d2 - => UnderLets.Base (#(ident.Z_neg_snd)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | None => - UnderLets.UnderLet x - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ => - UnderLets.UnderLet x - (fun v0 : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v0)%expr, - (- (#(ident.snd)%expr @ $v0)%expr_pat)%expr)%expr_pat) - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) - _ | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | - @expr.App _ _ _ s _ - (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.UnderLet x - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ - (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.UnderLet x - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - | _ => - UnderLets.UnderLet x - (fun v : var (type.base (base.type.Z * base.type.Z)%etype) => - UnderLets.Base - (#(ident.fst)%expr @ ($v)%expr, - (- (#(ident.snd)%expr @ $v)%expr_pat)%expr)%expr_pat) - end -| ident.Z_cast range => - fun x : expr (type.base base.type.Z) => - match x with - | #(idc)%expr_pat => - match - match idc with - | @ident.Literal t0 v => - match t0 as t1 return (base.base_interp t1 -> option Z) with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args => - UnderLets.Base - ##(ident.cast ident.cast_outside_of_range range args)%expr - | None => UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.Z_cast range)%expr @ x)%expr_pat - end -| ident.Z_cast2 range => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ #(idc)%expr_pat x1) x0 => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - (let (r1, r2) := range in - fun '(x2, x3) => - (ident.cast ident.cast_outside_of_range r1 - x2, - ident.cast ident.cast_outside_of_range r2 x3)) - (args0, args1) in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) - t2 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 - base.type.Z - (UnderLets.UnderLets base.type - ident var - (expr - (type.base - (base.type.Z * - base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base - base.type.Z)) => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * - base.type.Z) - (#(ident.Z_cast - (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast - (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base - (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ - x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t3 : base.type => expr (type.base t3)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t4 : base.type => - expr (type.base t4)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * - base.type.Z) - (#(ident.Z_cast - (fst range))%expr @ - ($(x' v0))%expr, - #(ident.Z_cast - (snd range))%expr @ - ($(x'0 v1))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ - x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * - base.type.Z) - (#(ident.Z_cast - (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast - (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ - x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident - var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr - (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * - base.type.Z) - (#(ident.Z_cast - (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast - (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ - x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | None => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => - expr (type.base t1)) t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) - => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * - base.type.Z) - (#(ident.Z_cast - (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast - (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | ($_)%expr => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v0 : expr (type.base t2) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v1 : expr (type.base t3) => - base.try_make_transport_cps - (fun t1 : base.type => expr (type.base t1)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * base.type.Z) - (#(ident.Z_cast (fst range))%expr @ - ($(x' v0))%expr, - #(ident.Z_cast (snd range))%expr @ - ($(x'0 v1))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => - UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - | @expr.LetIn _ _ _ _ _ _ _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * base.type.Z) - (#(ident.Z_cast (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun - _ : Compile.value' false s1 -> - Compile.value' true d1 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s1 -> d1)%ptype => - fun _ : Compile.value' false s1 -> Compile.value' true d1 - => - UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - | _ => - match - s0 as t2 - return - (Compile.value' false t2 -> - UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - with - | type.base t2 => - fun v : expr (type.base t2) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) t2 - base.type.Z - (UnderLets.UnderLets base.type ident var - (expr (type.base (base.type.Z * base.type.Z)%etype))) - (fun - a : option - (expr (type.base t2) -> - expr (type.base base.type.Z)) => - match a with - | Some x' => - match - s as t3 - return - (Compile.value' false t3 -> - UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - with - | type.base t3 => - fun v0 : expr (type.base t3) => - base.try_make_transport_cps - (fun t0 : base.type => expr (type.base t0)) - t3 base.type.Z - (UnderLets.UnderLets base.type ident var - (expr - (type.base - (base.type.Z * base.type.Z)%etype))) - (fun - a0 : option - (expr (type.base t3) -> - expr (type.base base.type.Z)) => - match a0 with - | Some x'0 => - (fv <-- do_again - (base.type.Z * base.type.Z) - (#(ident.Z_cast (fst range))%expr @ - ($(x' v))%expr, - #(ident.Z_cast (snd range))%expr @ - ($(x'0 v0))%expr)%expr_pat; - UnderLets.Base (id (id fv)))%under_lets - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun - _ : Compile.value' false s2 -> - Compile.value' true d2 => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x0) - | None => - UnderLets.Base - (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end) - | (s2 -> d2)%ptype => - fun _ : Compile.value' false s2 -> Compile.value' true d2 - => - UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end (Compile.reflect x1) - end - | None => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end - | @expr.App _ _ _ s _ (@expr.App _ _ _ s0 _ ($_)%expr _) _ | @expr.App _ - _ _ s _ (@expr.App _ _ _ s0 _ (@expr.Abs _ _ _ _ _ _) _) _ | @expr.App - _ _ _ s _ (@expr.App _ _ _ s0 _ (_ @ _)%expr_pat _) _ | @expr.App _ _ _ - s _ (@expr.App _ _ _ s0 _ (@expr.LetIn _ _ _ _ _ _ _) _) _ => - UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - | @expr.App _ _ _ s _ #(_)%expr_pat _ | @expr.App _ _ _ s _ ($_)%expr _ | - @expr.App _ _ _ s _ (@expr.Abs _ _ _ _ _ _) _ | @expr.App _ _ _ s _ - (@expr.LetIn _ _ _ _ _ _ _) _ => - UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - | _ => UnderLets.Base (#(ident.Z_cast2 range)%expr @ x)%expr_pat - end -| ident.fancy_add log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_add log2wordmax imm))) - (args0, args1) in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_add log2wordmax imm)%expr @ x)%expr_pat - end -| ident.fancy_addc log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - (let - '(a, b) := - ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_addc - log2wordmax imm))) - (args1, args2, args3) in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.fancy_addc log2wordmax - imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ - x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ - x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ - x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addc log2wordmax imm)%expr @ x)%expr_pat - end -| ident.fancy_sub log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - (let - '(a, b) := - ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_sub log2wordmax imm))) - (args0, args1) in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_sub log2wordmax imm)%expr @ x)%expr_pat - end -| ident.fancy_subb log2wordmax imm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - (let - '(a, b) := - ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_subb - log2wordmax imm))) - (args1, args2, args3) in - (##(a)%expr, ##(b)%expr)%expr_pat) - | None => - UnderLets.Base - (#(ident.fancy_subb log2wordmax - imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ - x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ - x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ - x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_subb log2wordmax imm)%expr @ x)%expr_pat - end -| ident.fancy_mulll log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_mulll log2wordmax))) - (args0, args1)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_mulll log2wordmax)%expr @ x)%expr_pat - end -| ident.fancy_mullh log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_mullh log2wordmax))) - (args0, args1)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_mullh log2wordmax)%expr @ x)%expr_pat - end -| ident.fancy_mulhl log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_mulhl log2wordmax))) - (args0, args1)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_mulhl log2wordmax)%expr @ x)%expr_pat - end -| ident.fancy_mulhh log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x0 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_mulhh log2wordmax))) - (args0, args1)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_mulhh log2wordmax)%expr @ x)%expr_pat - end -| ident.fancy_rshi log2wordmax x => - fun x0 : expr (type.base (base.type.Z * base.type.Z)%etype) => - match x0 with - | (#(idc) @ x2 @ x1)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x2 with - | #(idc0)%expr_pat => - match - match idc0 with - | @ident.Literal t1 v => - match - t1 as t2 return (base.base_interp t2 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args0 => - match x1 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_rshi log2wordmax x))) - (args0, args1)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end - | _ => - UnderLets.Base (#(ident.fancy_rshi log2wordmax x)%expr @ x0)%expr_pat - end -| ident.fancy_selc => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - ident.fancy_selc)) - (args1, args2, args3)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | None => - UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | None => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_selc)%expr @ x)%expr_pat - end -| ident.fancy_selm log2wordmax => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - (ident.fancy_selm - log2wordmax))) - (args1, args2, args3)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ - x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ - x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ - x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_selm log2wordmax)%expr @ x)%expr_pat - end -| ident.fancy_sell => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - ident.fancy_sell)) - (args1, args2, args3)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | None => - UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | None => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_sell)%expr @ x)%expr_pat - end -| ident.fancy_addm => - fun x : expr (type.base (base.type.Z * base.type.Z * base.type.Z)%etype) - => - match x with - | (#(idc) @ x1 @ x0)%expr_pat => - match - match idc with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x1 with - | (#(idc0) @ x3 @ x2)%expr_pat => - match - match idc0 with - | @ident.pair A B => Some (A, B) - | _ => None - end - with - | Some _ => - match x3 with - | #(idc1)%expr_pat => - match - match idc1 with - | @ident.Literal t2 v => - match - t2 as t3 - return (base.base_interp t3 -> option Z) - with - | base.type.unit => fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args1 => - match x2 with - | #(idc2)%expr_pat => - match - match idc2 with - | @ident.Literal t3 v => - match - t3 as t4 - return - (base.base_interp t4 -> option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => fun _ : nat => None - end v - | _ => None - end - with - | Some args2 => - match x0 with - | #(idc3)%expr_pat => - match - match idc3 with - | @ident.Literal t4 v => - match - t4 as t5 - return - (base.base_interp t5 -> - option Z) - with - | base.type.unit => - fun _ : unit => None - | base.type.Z => - fun v0 : Z => Some v0 - | base.type.bool => - fun _ : bool => None - | base.type.nat => - fun _ : nat => None - end v - | _ => None - end - with - | Some args3 => - UnderLets.Base - ##(ident.fancy.interp - (invert_Some - (ident.to_fancy - ident.fancy_addm)) - (args1, args2, args3)%core)%expr - | None => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | _ => - UnderLets.Base - (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | None => - UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | None => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat - end - | _ => UnderLets.Base (#(ident.fancy_addm)%expr @ x)%expr_pat - end -end - : Compile.value' true t -- cgit v1.2.3