commit 21952dc723a275319a82f559aea09814132e5881 Author: JanUlrich Date: Wed Sep 29 20:26:49 2021 +0200 FJ Unify. Step 1. Nicht funktionierendes FC diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..e69de29 diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..dbae93b --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.4.9 diff --git a/src/main/scala/hb/dhbw/FiniteClosure.scala b/src/main/scala/hb/dhbw/FiniteClosure.scala new file mode 100644 index 0000000..ad41ec8 --- /dev/null +++ b/src/main/scala/hb/dhbw/FiniteClosure.scala @@ -0,0 +1,85 @@ +package hb.dhbw + + +sealed abstract class Type +final case class TypeVariable(name : String) extends Type +final case class RefType(name : String, params : List[Type]) extends Type + +class FiniteClosure(val extendsRelations : Set[(RefType, RefType)]){ + + def superTypes(of : String) : Set[RefType] = Set(extendsRelations.map(p => (p._1.name, p._2)).toMap.get(of).get) + // extendsRelations.filter(p => p._1.name == of).map(p => superTypes(p._1.name)).flatten + extendsRelations.filter(p => p._1.name == of).map(_._1).head + def subTypes(of : String) : Set[RefType] =Set(extendsRelations.map(p => (p._1.name, p._2)).toMap.get(of).get) + //extendsRelations.filter(p => p._2.name == of).map(p => subTypes(p._2.name)).flatten + extendsRelations.filter(p => p._1.name == of).map(_._1).head + + def getFCType(name : String): RefType ={ + extendsRelations.map(it => it._1).find(it => it.name == name).get + } + /* + + def cartesianProduct[A](lists : List[Set[A]]) : Set[List[A]] ={ + + def listMultiply[A](inFront: Set[A], list: Set[List[A]]) = list.flatMap(s => inFront.map(element => element :: s)) + + if(lists.size == 1) { + lists.head.map(it => List(it)) + } + else{ + listMultiply(lists.head, cartesianProduct(lists.tail)) + } + + } + + //Kann wiederverwendet werden: + def replaceParams(newType : RefType, replace : RefType): RefType ={ + val fcType = getFCType(replace.name) + val replaceMap : Map[TypeVariable, Type] = fcType.params.map{case t: TypePlaceholder => t}.zip(replace.params).toMap + RefType(newType.name, newType.params.map{case t: TypePlaceholder => replaceMap(t) case r: RefType => replaceParams(r, replace) }) + } + + //TODO: Falsche Funktionen + def greater(than : SimpleType): Set[SimpleType] = { + than match { + case RefType(name, params) => { + val superTypesNoWildcard = superTypes(name).map(superType => replaceParams(superType, RefType(name, params) )) + superTypesNoWildcard + .flatMap(superType => { + cartesianProduct(superType.params.map(param => greaterArg(param))) + .map(parameterList => RefType(superType.name, parameterList)) + } + ) + } + case TypePlaceholder(name) => Set(than) + } + } + + def smaller(than : SimpleType): Set[SimpleType] = { + than match { + case RefType(name, params) => { + val subTypesNoWildcard = subTypes(name).map(subType => replaceParams(subType, RefType(name, params) )) + subTypesNoWildcard + .flatMap(subTypes => { + cartesianProduct(subTypes.params.map(param => smallerArg(param))) + .map(parameterList => RefType(subTypes.name, parameterList)) + } + ) + } + case TypePlaceholder(name) => Set(than) + } + } + + def greaterArg(t : UnifyType): Set[UnifyType] ={ + t match { //TODO not recursive yet + case RefType(name, params) => Set(t, SuperWildcard(RefType(name, params)), ExtendsWildcard(RefType(name, params))) + case other => Set(other) + } + } + + def smallerArg(t : UnifyType): Set[UnifyType] ={ + t match { //TODO not recursive yet + case RefType(name, params) => Set(t, SuperWildcard(RefType(name, params)), ExtendsWildcard(RefType(name, params))) + case other => Set(other) + } + } + */ +} \ No newline at end of file diff --git a/src/main/scala/hb/dhbw/Main.scala b/src/main/scala/hb/dhbw/Main.scala new file mode 100644 index 0000000..879b681 --- /dev/null +++ b/src/main/scala/hb/dhbw/Main.scala @@ -0,0 +1,25 @@ +package hb.dhbw + +import hb.dhbw.Unify.LessDot +; + +object Main { + + def main(args: Array[String]): Unit = { + val fcPair1 = (RefType("ArrayList", List(TypeVariable("A"))), RefType("List", List(TypeVariable("A")))) + val fcPair3 = (RefType("List", List(TypeVariable("A"))), RefType("Object", List())) + val fcPair2 = (RefType("MyMap", List(TypeVariable("A"), TypeVariable("B"))), RefType("Map", List(RefType("String", List(TypeVariable("A"))), TypeVariable("B")))) + val cTest = Set(Set(1,2), Set(4,3)) + val fc = new FiniteClosure(Set(fcPair1, fcPair2, fcPair3)) + val cart = Unify.cartesianProduct(cTest) + println(cart) + + val step1 = Unify.step1(Set(LessDot(TypeVariable("a"), TypeVariable("b")), + LessDot(TypeVariable("a"), RefType("List", List(RefType("Object", List()))))), fc) + println(step1) + //val replacedType = fc.replaceParams(RefType("List", List(TypePlaceholder("A"))), RefType("ArrayList", List(RefType("String", List())))) + //println(replacedType) + //val replacedType2 = fc.replaceParams(RefType("Map", List(RefType("String", List(TypePlaceholder("A"))), TypePlaceholder("B"))), RefType("MyMap", List(RefType("String", List()), RefType("Integer", List())))) + //println(replacedType2) + } +} \ No newline at end of file diff --git a/src/main/scala/hb/dhbw/Unify.scala b/src/main/scala/hb/dhbw/Unify.scala new file mode 100644 index 0000000..4eb70b2 --- /dev/null +++ b/src/main/scala/hb/dhbw/Unify.scala @@ -0,0 +1,51 @@ +package hb.dhbw + + +object Unify { + + sealed abstract class Constraint + final case class LessDot(left: Type, right: Type) extends Constraint + final case class EqualsDot(left: Type, right: Type) extends Constraint + + def unify(finiteClosure: FiniteClosure): Unit ={ + + } + + def step1(eq : Set[Constraint], fc: FiniteClosure) ={ + val eq1 = eq.filter(c => c match{ + case LessDot(TypeVariable(_), TypeVariable(_)) => true + case EqualsDot(TypeVariable(_), TypeVariable(_)) => true + case _ => false + }) + val cLessdotACons: Set[Set[Constraint]] = eq.map(c => c match{ + case LessDot(RefType(name,params), TypeVariable(a)) => + fc.superTypes(name) + .map(superType => EqualsDot(TypeVariable(a), RefType(superType.name, superType.params.map(fc.getFCType(name).params.zip(params).toMap))).asInstanceOf[Constraint]) + case _ => null + }).filter(s => s!=null) + //val mutatedCLessdotACons = cartesianProduct(cLessdotACons) + val aLessdotCCons: Set[Set[Constraint]] = eq.map(c => c match{ + case LessDot(TypeVariable(a),RefType(name,params)) => + fc.subTypes(name) + .map(subTypes => EqualsDot(TypeVariable(a), RefType(subTypes.name, subTypes.params.map(fc.getFCType(name).params.zip(params).toMap))).asInstanceOf[Constraint]) + case _ => null + }).filter(s => s!=null) + //val mutadedALessdotCCons = cartesianProduct(aLessdotCCons) + val eqSet = cartesianProduct((Set(Set(eq1))+cLessdotACons+aLessdotCCons).filter(s => !s.isEmpty)) + eqSet.map( s => s.flatten) + } + + def cartesianProduct[A](lists : Set[Set[A]]) : Set[Set[A]] ={ + + def listMultiply[A](inFront: Set[A], list: Set[Set[A]]) = list.flatMap(s => inFront.map(element => s + element)) + + if(lists.size == 1) { + lists.head.map(it => Set(it)) + } + else{ + listMultiply(lists.head, cartesianProduct(lists.tail)) + } + + } +} +