FIR: Extract foldFlow from joinFlow/unionFlow in PersistentLogicSystem

This commit is contained in:
Denis Zharkov
2020-05-28 17:44:24 +03:00
parent a3d6c42810
commit 14a41d91f6
@@ -105,44 +105,45 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
} }
override fun joinFlow(flows: Collection<PersistentFlow>): PersistentFlow { override fun joinFlow(flows: Collection<PersistentFlow>): PersistentFlow {
if (flows.isEmpty()) return createEmptyFlow() return foldFlow(
flows.singleOrNull()?.let { return it } flows,
mergeOperation = { statements -> this.or(statements).takeIf { it.isNotEmpty } },
val aliasedVariablesThatDontChangeAlias = computeAliasesThatDontChange(flows) computeVariables = { computeVariablesDiffWithCommonFlow ->
flows.map {
val commonFlow = flows.reduce(::lowestCommonFlow) computeVariablesDiffWithCommonFlow(it).toList()
val commonVariables = flows.map { }.intersectSets().takeIf { it.isNotEmpty() }
it.diffVariablesIterable(commonFlow, aliasedVariablesThatDontChangeAlias.keys).toList() }
}.intersectSets() )
.takeIf { it.isNotEmpty() }
?: return commonFlow
for (variable in commonVariables) {
val info = or(flows.map { it.getApprovedTypeStatementsDiff(variable, commonFlow) })
if (info.isEmpty) continue
commonFlow.addApprovedStatements(info)
}
commonFlow.addVariableAliases(aliasedVariablesThatDontChangeAlias)
updateAllReceivers(commonFlow)
return commonFlow
} }
override fun unionFlow(flows: Collection<PersistentFlow>): PersistentFlow { override fun unionFlow(flows: Collection<PersistentFlow>): PersistentFlow {
return foldFlow(
flows,
this::and,
computeVariables = { computeVariablesDiffWithCommonFlow ->
flows.flatMapTo(mutableSetOf()) {
computeVariablesDiffWithCommonFlow(it)
}
}
)
}
private inline fun foldFlow(
flows: Collection<PersistentFlow>,
mergeOperation: (Collection<TypeStatement>) -> MutableTypeStatement?,
computeVariables: (computeVariablesDiffWithCommonFlow: (PersistentFlow) -> Iterable<RealVariable>) -> Collection<RealVariable>?
): PersistentFlow {
if (flows.isEmpty()) return createEmptyFlow() if (flows.isEmpty()) return createEmptyFlow()
flows.singleOrNull()?.let { return it } flows.singleOrNull()?.let { return it }
val aliasedVariablesThatDontChangeAlias = computeAliasesThatDontChange(flows) val aliasedVariablesThatDontChangeAlias = computeAliasesThatDontChange(flows)
val commonFlow = flows.reduce(::lowestCommonFlow) val commonFlow = flows.reduce(::lowestCommonFlow)
val allVariables = flows.flatMapTo(mutableSetOf()) { val variables =
it.diffVariablesIterable(commonFlow, aliasedVariablesThatDontChangeAlias.keys) computeVariables { it.diffVariablesIterable(commonFlow, aliasedVariablesThatDontChangeAlias.keys) } ?: return commonFlow
}
for (variable in allVariables) { for (variable in variables) {
val info = and(flows.map { it.getApprovedTypeStatementsDiff(variable, commonFlow) }) val info = mergeOperation(flows.map { it.getApprovedTypeStatementsDiff(variable, commonFlow) }) ?: continue
commonFlow.addApprovedStatements(info) commonFlow.addApprovedStatements(info)
} }