在scala中,如何防止编译器循环调用隐式前提?如何避免它们

在scala中,如何防止编译器循环调用隐式前提?如何避免它们,scala,implicit,homotopy-type-theory,Scala,Implicit,Homotopy Type Theory,我正在为scala中的Curry Howard同构编写一个实现,一系列证明可以定义为实现以下特征的对象: (完整代码回购上传至) trait-proof-system[OUB]{//TODO:没有IUB? 特征命题扩展可序列化{ 型密码域 *@tparam I src类型 *@tparam-P-tgt型 */ 类=>^^[-I,P )扩展可以证明[I,P]{ 超控def应用(v:I):P=车顶(v) } 键入-->[-I,O[-I,+O>[-I,O )extends=>>^[I,Proposit

我正在为scala中的Curry Howard同构编写一个实现,一系列证明可以定义为实现以下特征的对象:

(完整代码回购上传至)

trait-proof-system[OUB]{//TODO:没有IUB?
特征命题扩展可序列化{
型密码域
*@tparam I src类型
*@tparam-P-tgt型
*/
类=>^^[-I,P
)扩展可以证明[I,P]{
超控def应用(v:I):P=车顶(v)
}
键入-->[-I,O[-I,+O>[-I,O
)extends=>>^[I,Proposition.ToBe[O]](v=>Proposition.ToBe(toOut(v)))
来自[I]:工厂[I]=新工厂[I]()
类工厂[I](){
def=>^^[P=new(I=>^^P)(fn)
def=>>[O)=新(I=>>O)(fn)
}
def at[I](v:I)=新召唤师[I](v)
职业召唤师[I](v:I)扩展工厂[I]{
隐式def召唤[P{src=>
val p1:p1=lemma1.valueOf(src.s1)
引理2.3(
副本(p1)
)
}
}
}
编译器似乎陷入了循环证明的解决方案中:它试图自己实现
定理的
引理2
。如果我将2个隐式合并为1,问题就消失了:

隐式def asLeaf[
S1>{src=>
val keys:N#keys=src.newNames.keys
val p1:p1=引理值(src.s1)
val值:P1##U维度#静态=P1.Dimensions.Static
val zipped:HO=values.zipWithKeys(键)
叶子形状。FromRecord(压缩)
}
}
因此,我的问题是:

  • 为什么会发生这种情况?scala编译器算法的什么变化可以消除任何循环搜索

  • 如何手动规避此错误


  • 我还意识到同伦类型理论()的规范化实现实际上在运行时进行了大部分推理,而不是在编译时进行推理,这似乎违背了目的。也许这个错误是原因之一?

    请准备一个最小的自包含示例(这样就不需要克隆整个回购协议,可以使用自己最喜欢的构建工具,如sbt而不是gradle等)。我正在尝试这样做,(这个小小的ProofSystemSpike就是为了这个目的)。但它不会触发死循环,因为它会触发死循环(需要定义
    形状
    叶形
    名称等)。否则(如果不需要定义),什么是“死循环”的最小示例?