anchor.diff:                          | [t0; t1; t2; t3; t4; t5; t6; t7; t8; t9; t10; t11; t12; t13; t14; t15; t16; t17; t18; t19; t20; t21; t22; t23; t24; t25; t26; t27; t28; t29; t30] -> typedefof<WrappedDispatcher<_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_>>.MakeGenericType [| t0; t1; t2; t3; t4; t5; t6; t7; t8; t9; t10; t11; t12; t13; t14; t15; t16; t17; t18; t19; t20; t21; t22; t23; t24; t25; t26; t27; t28; t29; t30; ret |]
                           | _ -> failwith "[Ag] too many strict arguments"
   
  -        [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  -        module SemanticFunctions =
  -            open Aardvark.Base.Monads.Option
  -
  -            type Type with
  -                member x.MaybeAssignableFromSubtype(other : Type) =
  -                    if x.IsAssignableFrom other then true
  -                    elif other.IsAssignableFrom x then true
  -                    else other.IsInterface
  -
  -            let private assign = Aardvark.Base.QuotationReflectionHelpers.getMethodInfo <@@ (<<=) @@>
  -            let private dyn = Aardvark.Base.QuotationReflectionHelpers.getMethodInfo <@@ (?) @@>
  -            let private scopeProp = typeof<Globals.Marker>.DeclaringType.GetProperty("scope")
  -            let private instance = typeof<Globals.Marker>.DeclaringType.GetMethod("getTypedInstance")
  -            let private inheritMeth = typeof<Scope>.GetMethod("InheritInternal")
  -
  -            let (|Scope|_|) (e : Expr) =
  -                match e with
  -                    | PropertyGet(None, p, []) when p = scopeProp ->
  -                        Some ()
  -                    | _ ->
  +    open GenericStuff
  +
  +
  +    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
  +    module SemanticFunctions =
  +        open Aardvark.Base.Monads.Option
  +
  +        type Type with
  +            member x.MaybeAssignableFromSubtype(other : Type) =
  +                if x.IsAssignableFrom other then true
  +                elif other.IsAssignableFrom x then true
  +                else other.IsInterface
  +
  +        let private assign = Aardvark.Base.QuotationReflectionHelpers.getMethodInfo <@@ (<<=) @@>
  +        let private dyn = Aardvark.Base.QuotationReflectionHelpers.getMethodInfo <@@ (?) @@>
  +        let private scopeProp = typeof<Globals.Marker>.DeclaringType.GetProperty("scope")
  +        let private scopeMeth = typeof<Scope>.DeclaringType.GetMethod("getScope")
  +        let private instance = typeof<Globals.Marker>.DeclaringType.GetMethod("getTypedInstance")
  +        let private inheritMeth = typeof<Scope>.GetMethod("InheritInternal")
  +
  +        let (|Scope|_|) (e : Expr) =
  +            match e with
  +                | PropertyGet(None, p, []) when p = scopeProp ->
  +                    Some ()
  +                | Call(None, m, []) when m = scopeMeth ->
  +                    Some ()
  +                | _ ->
  +                    None
  +
  +
  +        module private List =
  +            let rec mapOpt (f : 'a -> Option<'b>) (l : list<'a>) : Option<list<'b>> =
  +                match l with
  +                    | [] -> Some []
  +                    | h :: rest ->
  +                        match f h with
  +                            | Some v -> 
  +                                match mapOpt f rest with
  +                                    | Some rest -> Some (v :: rest)
  +                                    | None -> None
  +                            | None ->
  +                                None
  +
  +        let rec private tryGetInheritType (e : Expr) =
  +            match e with
  +                | AssignInherit(v) -> Some v.Type
  +                | ShapeVar(_) -> None
  +                | ShapeLambda(_,b) -> tryGetInheritType b
  +                | ShapeCombination(o, args) -> args |> List.tryPick tryGetInheritType
  +
  +        let rec private visit (syn : HashSet<string>) (inh : HashSet<string>) (retType : byref<Type>) (kind : byref<AttributeKind>) (e : Expr) =
  +            match e with
  +                | AssignInherit(value) ->
  +                    kind <- AttributeKind.Inherited
  +                    retType <- value.Type
  +                    visit syn inh &retType &kind value
  +
  +                | Inherit(name, o) -> 
  +                    inh.Add name |> ignore
  +                    visit syn inh &retType &kind o
  +
  +                | Synthesize(name, o) ->
  +                    syn.Add name |> ignore
  +                    visit syn inh &retType &kind o
  +
  +                | ShapeVar _ -> ()
  +                | ShapeLambda(_,b) -> visit syn inh &retType &kind b
  +                | ShapeCombination(o,args) -> for a in args do visit syn inh &retType &kind a
  +
  +        let ofMethods (name : string) (methods : list<MethodInfo>) =
  +            option {
  +
  +                let expressions =
  +                    methods |> List.choose (fun m ->
  +                        if m.ReturnType.ContainsGenericParameters then
  +                            Log.warn "[Ag] semantic functions may not return generic values '%s'" m.PrettyName
  +                            None
  +                        else
  +                            match Expr.TryGetReflectedDefinition m with
  +                                | Some e -> Some (m, e)
  +                                | None ->
  +                                    Log.warn "[Ag] could not get reflected definition for semantic function '%s'" m.PrettyName
  +                                    None
  +                    )
  +
  +
  +                let functions =
  +                    expressions |> List.map (fun (mi, e) ->
  +                        
  +                        let syn = HashSet<string>()
  +                        let inh = HashSet<string>()
  +                        let mutable ret = mi.ReturnType
  +                        let mutable kind = AttributeKind.Synthesized
  +                        visit syn inh &ret &kind e
  +
  +                        let isRoot =
  +                            let parameters = mi.GetParameters()
  +                            if parameters.Length = 1 then
  +                                let t = parameters.[0].ParameterType
  +                                t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<Root<_>>
  +                            else
  +                                false
  +
  +                        let func = 
  +                            {
  +                                original    = mi
  +                                code        = e
  +                                isRoot      = isRoot
  +                                kind        = kind
  +                                name        = name
  +                                nodeType    = mi.GetParameters().[0].ParameterType
  +                                inherits    = HashSet.toSet inh
  +                                synthesizes = HashSet.toSet syn
  +                            }
  +
  +                        ret, kind, func
  +                    )
  +
  +                let! kind = 
  +                    match functions |> List.fold (fun k (_,kk,_) -> k ||| kk) AttributeKind.None with
  +                        | AttributeKind.Mixed | AttributeKind.None -> 
  +                            Log.warn "[Ag] attribute '%s' has conflicting kinds (omitting)" name 
  +                            None
  +                        | kind -> 
  +                            Some kind
  +
  +                let! retType =
  +                    let retTypes = functions |> List.map (fun (t,_,_) -> t) |> HashSet
  +                    if retTypes.Count = 1 then Some (Seq.head retTypes)
  +                    else 
  +                        Log.warn "[Ag] rules for %s have ambigous return types: [%s]" name (retTypes |> Seq.map (fun t -> t.PrettyName) |> String.concat "; ")
                           None
   
  -
  -            module private List =
  -                let rec mapOpt (f : 'a -> Option<'b>) (l : list<'a>) : Option<list<'b>> =
  -                    match l with
  -                        | [] -> Some []
  -                        | h :: rest ->
  -                            match f h with
  -                                | Some v -> 
  -                                    match mapOpt f rest with
  -                                        | Some rest -> Some (v :: rest)
  -                                        | None -> None
  -                                | None ->
  -                                    None
  -
  -            let rec private tryGetInheritType (e : Expr) =
  -                match e with
  -                    | AssignInherit(v) -> Some v.Type
  -                    | ShapeVar(_) -> None
  -                    | ShapeLambda(_,b) -> tryGetInheritType b
  -                    | ShapeCombination(o, args) -> args |> List.tryPick tryGetInheritType
  -
  -
  -            let rec private visit (syn : HashSet<string>) (inh : HashSet<string>) (retType : byref<Type>) (kind : byref<AttributeKind>) (e : Expr) =
  -                match e with
  -                    | AssignInherit(value) ->
  -                        kind <- AttributeKind.Inherited
  -                        retType <- value.Type
  -                        visit syn inh &retType &kind value
  -
  -                    | Inherit(name, o) -> 
  -                        inh.Add name |> ignore
  -                        visit syn inh &retType &kind o
  -
  -                    | Synthesize(name, o) ->
  -                        syn.Add name |> ignore
  -                        visit syn inh &retType &kind o
  -
  -                    | ShapeVar _ -> ()
  -                    | ShapeLambda(_,b) -> visit syn inh &retType &kind b
  -                    | ShapeCombination(o,args) -> for a in args do visit syn inh &retType &kind a
  -
  -
  -            let ofMethods (name : string) (methods : list<MethodInfo>) =
  -                option {
  -
  -                    let expressions =
  -                        methods |> List.choose (fun m ->
  -                            if m.ReturnType.ContainsGenericParameters then
  -                                Log.warn "[Ag] semantic functions may not return generic values '%s'" m.PrettyName
  -                                None
  -                            else
  -                                match Expr.TryGetReflectedDefinition m with
  -                                    | Some e -> Some (m, e)
  -                                    | None ->
  -                                        Log.warn "[Ag] could not get reflected definition for semantic function '%s'" m.PrettyName
  -                                        None
  -                        )
  -
  -
  -                    let functions =
  -                        expressions |> List.map (fun (mi, e) ->
  -                        
  -                            let syn = HashSet<string>()
  -                            let inh = HashSet<string>()
  -                            let mutable ret = mi.ReturnType
  -                            let mutable kind = AttributeKind.Synthesized
  -                            visit syn inh &ret &kind e
  -
  -                            let isRoot =
  -                                let parameters = mi.GetParameters()
  -                                if parameters.Length = 1 then
  -                                    let t = parameters.[0].ParameterType
  -                                    t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<Root<_>>
  -                                else
  -                                    false
  -
  -                            let func = 
  -                                {
  -                                    original    = mi
  -                                    code        = e
  -                                    isRoot      = isRoot
  -                                    kind        = kind
  -                                    name        = name
  -                                    nodeType    = mi.GetParameters().[0].ParameterType
  -                                    inherits    = HashSet.toSet inh
  -                                    synthesizes = HashSet.toSet syn
  -                                }
  -
  -                            ret, kind, func
  -                        )
  -
  -                    let! kind = 
  -                        match functions |> List.fold (fun k (_,kk,_) -> k ||| kk) AttributeKind.None with
  -                            | AttributeKind.Mixed | AttributeKind.None -> 
  -                                Log.warn "[Ag] attribute '%s' has conflicting kinds (omitting)" name 
  -                                None
  -                            | kind -> 
  -                                Some kind
  -
  -                    let! retType =
  -                        let retTypes = functions |> List.map (fun (t,_,_) -> t) |> HashSet
  -                        if retTypes.Count = 1 then Some (Seq.head retTypes)
  -                        else 
  -                            Log.warn "[Ag] rules for %s have ambigous return types: [%s]" name (retTypes |> Seq.map (fun t -> t.PrettyName) |> String.concat "; ")
  -                            None
  -
  -                    return {
  -                        index           = Globals.getAttributeIndex name
  -                        name            = name
  -                        kind            = kind
  -                        valueType       = retType
  -                        functions       = functions |> List.map (fun (_,_,f) -> f)
  +                return {
  +                    index           = Globals.getAttributeIndex name
  +                    name            = name
  +                    kind            = kind
  +                    valueType       = retType
  +                    functions       = functions |> List.map (fun (_,_,f) -> f)
  +                }
  +            }
  +  
  +        let getMoreSpecific (t : Type) (sf : SemanticFunctions) : list<SemanticFunction> =
  +            let mutable foundSelf = false
  +
  +            let functions = 
  +                sf.functions |> List.filter (fun sf ->
  +                    if sf.nodeType = t then foundSelf <- true
  +                    t.MaybeAssignableFromSubtype sf.nodeType
  +                )
  +
  +            if foundSelf then
  +                functions
  +            else
  +                //<@ fun (x : #t) -> inh <<= (x?name : 'valueType) @>
  +                let autoInherit = 
  +                    let assign = assign.MakeGenericMethod [|sf.valueType|]
  +                    let dyn = dyn.MakeGenericMethod [| t; sf.valueType |]
  +                    let self = Var("node", t)
  +                    Expr.Lambda(
  +                        self,
  +                        Expr.Call(assign, [Expr.Value(inh); Expr.Call(dyn, [Expr.Var self; Expr.Value(sf.name)])])
  +                    )
  +
  +                let self =
  +                    {
  +                        name        = sf.name
  +                        kind        = sf.kind
  +                        original    = null
  +                        nodeType    = t
  +                        code        = autoInherit
  +                        isRoot      = false
  +                        inherits    = Set.ofList [sf.name]
  +                        synthesizes = Set.empty
                       }
  -                }
  -  
  -            let getMoreSpecific (t : Type) (sf : SemanticFunctions) : list<SemanticFunction> =
  -                let mutable foundSelf = false
  -
  -                let functions = 
  -                    sf.functions |> List.filter (fun sf ->
  -                        if sf.nodeType = t then foundSelf <- true
  -                        t.MaybeAssignableFromSubtype sf.nodeType
  -                    )
  -
  -                if foundSelf then
  -                    functions
  -                else
  -                    //<@ fun (x : #t) -> inh <<= (x?name : 'valueType) @>
  -                    let autoInherit = 
  -                        let assign = assign.MakeGenericMethod [|sf.valueType|]
  -                        let dyn = dyn.MakeGenericMethod [| t; sf.valueType |]
  -                        let self = Var("node", t)
  -                        Expr.Lambda(
  -                            self,
  -                            Expr.Call(assign, [Expr.Value(inh); Expr.Call(dyn, [Expr.Var self; Expr.Value(sf.name)])])
  -                        )
  -
  -                    let self =
  -                        {
  -                            name        = sf.name
  -                            kind        = sf.kind
  -                            original    = null
  -                            nodeType    = t
  -                            code        = autoInherit
  -                            isRoot      = false
  -                            inherits    = Set.ofList [sf.name]
  -                            synthesizes = Set.empty
  -                        }
  -
  -                    self :: functions
  -
  -
  -            let private inlineSemTypes(e : Expr) = 
  -                match e with
  -                    | Lambda(v,b) when v.Type.IsDefined(typeof<SemanticAttribute>) ->
  -                        let value = Expr.Value(Globals.getInstance v.Type, v.Type)
  -                        b.Substitute (fun vi -> if vi = v then Some value else None)
  -                    | _ -> e
  -
  -            let private force (msg : string) (o : Option<'a>) =
  -                match o with
  -                    | Some o -> o
  -                    | None -> failwith msg
  -
  -            let private convert (selfVar : Var) (scopeType : Type) (assumeStrict : Map<string, int>) (sf : SemanticFunction) =
  -                let code = 
  -                    match inlineSemTypes sf.code with
  -                        | Lambda(node, body) ->   
  -                            let vscope = Var("scope", scopeType)
  -                            let scope = Expr.Var vscope
  -                            let rec repair (e : Expr) =
  -                                match e with
  -                                    | Scope ->
  -                                        scope
  -
  -                                    | Synthesize(name, node) ->
  -                                        let node = repair node
  -                                        let td = selfVar.Type
  -                                        let dispatcher =
  -                                            if name = sf.name then 
  -                                                Expr.Var selfVar
  -                                            else 
  -                                                let index = Globals.getAttributeIndex name
  -                                                let dispatcher = <@@ Globals.synDispatchers.[index] @@>
  -                                                Expr.Coerce(dispatcher, td)
  -
  -                                        let vo = Var("child", typeof<obj>)
  -                                        let o = Expr.Var vo
  -                                        let childScope = Var("childScope", scopeType)
  -
  -                                        let invoke = td.GetMethod("Invoke") //MethodInfo.Create(td, "Invoke", [|typeof<obj>; scopeType|], e.Type)
  -                                        let getChild = scopeType.GetMethod("ChildScope", BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.DeclaredOnly) //MethodInfo.Create(scope.Type, "ChildScope", [| typeof<obj> |], scope.Type)
  -
  -                                        Expr.Let(
  -                                            vo, Expr.Coerce(node, typeof<obj>), 
  -                                            Expr.Let(
  -                                                childScope, Expr.Call(scope, getChild, [o]),
  -                                                Expr.Call(dispatcher, invoke, [o; Expr.Var childScope])
  -                                            )
  -                                        )
  -
  -                                    | Inherit(name,node) ->
  -                                        let node = repair node
  -
  -                                        match Map.tryFind name assumeStrict with
  -                                            | Some i ->
  -                                                let field = scopeType.GetField(sprintf "F%d" i)
  -                                                Expr.FieldGet(scope, field)
  -
  -                                            | None -> 
  -                                        
  -                                                let inh = inheritMeth.MakeGenericMethod [|e.Type|]
  -                                                let td = typedefof<Dispatcher<_,_>>.MakeGenericType [| scopeType; e.Type |]
  -                                                let tr = typedefof<Dispatcher<_>>.MakeGenericType [| e.Type |]
  -                                                let index = Globals.getAttributeIndex name
  -                                                let dispatcher = 
  -                                                    if name = sf.name then Expr.Var(selfVar)
  -                                                    else Expr.Coerce(<@@ Globals.inhDispatchers.[index] @@>, td)
  -                                                let rootDispatcher = Expr.Coerce(<@@ Globals.rootDispatchers.[index] @@>, tr)
  -                                        
  -                                                Expr.Call(scope, inh, [Expr.Value(index); dispatcher; rootDispatcher])
  -
  -                                    | AssignInherit(value) ->
  -                                        repair value
  -
  -                                    | ShapeVar _ -> e
  -                                    | ShapeLambda(v,b) -> Expr.Lambda(v, repair b)
  -                                    | ShapeCombination(o, args) -> RebuildShapeCombination(o, args |> List.map repair)
  -
  -
  -
  -                            let body = repair body
  -
  -                            Expr.Lambda(node, Expr.Lambda(vscope, body))
  -                            //attName, [node; vscope], repair body
  -                        | _ ->
  -                            failwith "sadasdasdasdasd"
  -
  -                { sf with code = code }
  -
  -            let private addStrictInh (selfVar : Var) (scopeType : Type) (strict : Map<string, int>) (sf : SemanticFunctions) (otherSF : SemanticFunctions) =
  -                { sf with
  -                    functions =
  -                        sf.functions |> List.collect (fun synSF ->
  -                            let inhIndex = otherSF.index
  -                            let other = otherSF |> getMoreSpecific synSF.nodeType
  -                            let field = scopeType.GetField(sprintf "F%d" strict.[otherSF.name])
  -
  -                            other |> List.map (fun inhSF ->
  -                                let inhSF = convert selfVar scopeType strict inhSF
  -                                match inhSF.code, synSF.code with
  -                                    | Lambda(ni, Lambda(si, inh)), Lambda(ns, Lambda(ss, syn)) ->
  -                                        let nf =
  -                                            if ni.Type.IsAssignableFrom ns.Type then ns
  -                                            elif ns.Type.IsAssignableFrom ni.Type then ni
  -                                            else failwith "[Ag] interface-inherit rules not implemented atm."
  -
  -                                        let rec inlineInh (e : Expr) =
  -                                            match e with
  -                                                | Let(cs, (Call(Some s, mi, [n]) as childScope), body) when mi.Name = "ChildScope" && typeof<Scope>.IsAssignableFrom mi.DeclaringType ->
  -                                                    Expr.Let(
  -                                                        cs, inlineInh childScope,
  -                                                        Expr.Sequential(
  -                                                            Expr.FieldSet(Expr.Var cs, field, inh),
  -                                                            //Expr.Call(Expr.Var cs, scopeSet, [Expr.Value(inhIndex); Expr.Coerce(inh, typeof<obj>)]),
  -                                                            inlineInh body
  -                                                        )
  -                                                    )
  -                                                
  -                                                | ShapeVar v ->
  -                                                    if v = ns then Expr.Var nf
  -                                                    elif v = ni then Expr.Var nf
  -                                                    elif v = ss then Expr.Var si
  -                                                    else e
  -                                                | ShapeLambda(v,b) ->
  -                                                    Expr.Lambda(v, inlineInh b)
  -                                                | ShapeCombination(o, args) ->
  -                                                    RebuildShapeCombination(o, args |> List.map inlineInh)
  -
  -                                        { synSF with 
  -                                            nodeType = nf.Type
  -                                            code = Expr.Lambda(nf, Expr.Lambda(si, inlineInh syn)) 
  -                                        }
  -
  -                                    | _ ->
  -                                        failwith ""
  -                            )
  -
  -                        )
  -                }
  -
  -            let private compileNormal (sf : SemanticFunctions) =
  -                let strictInh =
  -                    match sf.kind with
  -                        | AttributeKind.Synthesized ->
  -                            sf.functions
  -                                |> List.filter (fun sf ->Set.isEmpty sf.synthesizes)
  -                                |> List.map (fun sf -> sf.inherits)
  -                                |> Set.intersectMany
  -                        | _ ->
  -                            Set.empty
  -
  -                let inhIndices = strictInh |> Seq.mapi (fun i n -> (n,i)) |> Seq.toList
  -                let types = inhIndices |> List.map (fun (n,i) -> semanticFunctions.[n].valueType)
  -                let attributeIndices = strictInh |> Seq.map (fun n -> Globals.getAttributeIndex(n)) |> Seq.toList
  -                let strictInh = Map.ofList inhIndices
  -
  -                let scopeType = Scope.getType types
  -                let dispType = WrappedDispatcher.getType sf.valueType types
  -
  -                let dispType = dispType
  -                let selfDisp = Var(sprintf "self_%s" (Guid.NewGuid().ToString("N")), dispType)
  -
  -                let dispatcher =
  -                    let mutable final = { sf with functions = sf.functions |> List.map (fun sf -> convert selfDisp scopeType strictInh sf) }
  -                    for (KeyValue(s,_)) in strictInh do
  -                        let other = semanticFunctions.[s]
  -                        final <- addStrictInh selfDisp scopeType strictInh final other
  -
  -                    let methods = 
  -                        final.functions |> List.choose (fun e ->
  -                            match e.code with
  -                                | Lambda(n,Lambda(s, body)) -> Some (sf.name, [n;Var(s.Name, scopeType)], fun _ -> body)
  -                                | _ -> None
  -                        )
  -
  -                    let tModule = 
  -                        Compiler.compile {
  -                            Name = sf.name
  -                            Declarations =
  -                            [
  -                                Class {
  -                                    Name = "Sem"
  -                                    Arguments = [ selfDisp ]
  -                                    BaseType = None
  -                                    Fields = []
  -                                    Members = methods
  -                                }
  -                            ]
  -                        }
  -
  -                    let tSem = tModule.GetNestedType("Sem")
  -                    let semCtor = tSem.GetConstructors().[0]
  -
  -                    let mutable table = None
  -                    let getTable (self : obj) =
  -                        match table with
  -                            | Some t -> t
  -                            | None ->
  -                                let instance = Activator.CreateInstance(tSem, self)
  -                                let methods = tSem.GetMethods(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.DeclaredOnly)
  -                                let t = 
  -                                    MethodTable.ofList [
  -                                        for m in methods do
  -                                            yield instance, m
  -                                    ]
  -                                table <- Some t
  -                                t
  -            
  -                    let resolve (self : obj) (t : Type) =
  -                        self |> getTable |> MethodTable.tryResolve [| t; scopeType |]   
  -                            
  -                    let tResolve = typeof<obj -> Type -> Option<obj * MethodInfo>>
  -                    let tIndices = attributeIndices |> List.map (fun _ -> typeof<int>) |> List.toArray
  -                
  -
  -                    let dispCtor = dispType.GetConstructor (Array.append tIndices [|tResolve|])
  -                    let disp = dispCtor.Invoke (Array.append (List.toArray (List.map (fun a -> a :> obj) attributeIndices)) [|resolve|])
  -                
  -                    disp |> unbox<IObjectDispatcher2>
  -
  -                dispatcher
  -
  -            let private compileRoot (attName : string) (valueType : Type) (methods : list<SemanticFunction>) =
  -                let td = typedefof<Dispatcher<_>>.MakeGenericType [| valueType |]
  -                let ctor = td.GetConstructor [| typeof<obj -> Type -> Option<obj * MethodInfo>> |]
  -                let realMethods =
  -                    methods |> List.mapi (fun i sf ->
  -                        let mi = sf.original
  -                        if mi.IsGenericMethod then
  -                            failwith "[Ag] root rules must not be generic"
  -
  -                        let e = Expr.TryGetReflectedDefinition(mi) |> force "not possible"
  +
  +                self :: functions
  +
  +
  +        let private inlineSemTypes(e : Expr) = 
  +            match e with
  +                | Lambda(v,b) when v.Type.IsDefined(typeof<SemanticAttribute>) ->
  +                    let value = Expr.Value(Globals.getInstance v.Type, v.Type)
  +                    b.Substitute (fun vi -> if vi = v then Some value else None)
  +                | _ -> e
  +
  +        let private force (msg : string) (o : Option<'a>) =
  +            match o with
  +                | Some o -> o
  +                | None -> failwith msg
  +
  +        let private convert (selfVar : Var) (scopeType : Type) (assumeStrict : Map<string, int>) (sf : SemanticFunction) =
  +            let code = 
  +                match inlineSemTypes sf.code with
  +                    | Lambda(node, body) ->   
  +                        let vscope = Var("scope", scopeType)
  +                        let scope = Expr.Var vscope
                           let rec repair (e : Expr) =
                               match e with
  -                                | Scope -> failwith "[Ag] root rules must not use the current scope"
  -                                | Synthesize(name, node) -> failwith "[Ag] root rules must not synthesize attributes"
  -                                | Inherit(name) -> failwith "[Ag] root rules must not inherit attributes"
  +                                | Scope ->
  +                                    scope
  +
  +                                | Synthesize(name, node) ->
  +                                    let node = repair node
  +                                    let td = selfVar.Type
  +                                    let dispatcher =
  +                                        if name = sf.name then 
  +                                            Expr.Var selfVar
  +                                        else 
  +                                            let index = Globals.getAttributeIndex name
  +                                            let dispatcher = <@@ Globals.synDispatchers.[index] @@>
  +                                            Expr.Coerce(dispatcher, td)
  +
  +                                    let vo = Var("child", typeof<obj>)
  +                                    let o = Expr.Var vo
  +                                    let childScope = Var("childScope", scopeType)
  +
  +                                    let invoke = td.GetMethod("Invoke") //MethodInfo.Create(td, "Invoke", [|typeof<obj>; scopeType|], e.Type)
  +                                    let getChild = scopeType.GetMethod("ChildScope", BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.DeclaredOnly) //MethodInfo.Create(scope.Type, "ChildScope", [| typeof<obj> |], scope.Type)
  +
  +                                    Expr.Let(
  +                                        vo, Expr.Coerce(node, typeof<obj>), 
  +                                        Expr.Let(
  +                                            childScope, Expr.Call(scope, getChild, [o]),
  +                                            Expr.Call(dispatcher, invoke, [o; Expr.Var childScope])
  +                                        )
  +                                    )
  +
  +                                | Inherit(name,node) ->
  +                                    let node = repair node
  +
  +                                    match Map.tryFind name assumeStrict with
  +                                        | Some i ->
  +                                            let field = scopeType.GetField(sprintf "F%d" i)
  +                                            Expr.FieldGet(scope, field)
  +
  +                                        | None -> 
  +                                        
  +                                            let inh = inheritMeth.MakeGenericMethod [|e.Type|]
  +                                            let td = typedefof<Dispatcher<_,_>>.MakeGenericType [| scopeType; e.Type |]
  +                                            let tr = typedefof<Dispatcher<_>>.MakeGenericType [| e.Type |]
  +                                            let index = Globals.getAttributeIndex name
  +                                            let dispatcher = 
  +                                                if name = sf.name then Expr.Var(selfVar)
  +                                                else Expr.Coerce(<@@ Globals.inhDispatchers.[index] @@>, td)
  +                                            let rootDispatcher = Expr.Coerce(<@@ Globals.rootDispatchers.[index] @@>, tr)
  +                                        
  +                                            Expr.Call(scope, inh, [Expr.Value(index); dispatcher; rootDispatcher])
   
                                   | AssignInherit(value) ->
  -                                    value
  +                                    repair value
   
                                   | ShapeVar _ -> e
                                   | ShapeLambda(v,b) -> Expr.Lambda(v, repair b)
                                   | ShapeCombination(o, args) -> RebuildShapeCombination(o, args |> List.map repair)
   
  -                        match repair (inlineSemTypes e) with
  -                            | Lambda(v,body) ->
  -                                let free = body.GetFreeVars() |> Set.ofSeq
  -                                let t = v.Type.GetGenericArguments().[0]
  -                                if Set.isEmpty free then 
  -                                    attName, [Var(v.Name, t)], body
  -                                else 
  -                                    failwith "[Ag] root rule does not take an argument"
  -                            | _ -> 
  +
  +
  +                        let body = repair body
  +
  +                        let body =
  +                            if sf.kind = AttributeKind.Synthesized then
  +                                let s = Expr.Coerce(scope, typeof<Scope>)
  +                                let old = Var("oldScope", typeof<Scope>)
  +                                let set (s : Expr) = <@@ CurrentScope.Instance <- (%%s : Scope) @@>
  +                                Expr.Let(
  +                                    old, <@ CurrentScope.Instance @>,
  +                                    Expr.TryFinally(
  +                                        Expr.Sequential(set s, body),
  +                                        set (Expr.Var old)
  +                                    )
  +                                )
  +                            else
  +                                body
  +
  +                        Expr.Lambda(node, Expr.Lambda(vscope, body))
  +                        //attName, [node; vscope], repair body
  +                    | _ ->
  +                        failwith "sadasdasdasdasd"
  +
  +            { sf with code = code }
  +
  +        let private addStrictInh (selfVar : Var) (scopeType : Type) (strict : Map<string, int>) (sf : SemanticFunctions) (otherSF : SemanticFunctions) =
  +            { sf with
  +                functions =
  +                    sf.functions |> List.collect (fun synSF ->
  +                        let inhIndex = otherSF.index
  +                        let other = otherSF |> getMoreSpecific synSF.nodeType
  +                        let field = scopeType.GetField(sprintf "F%d" strict.[otherSF.name])
  +
  +                        other |> List.map (fun inhSF ->
  +                            let inhSF = convert selfVar scopeType strict inhSF
  +                            match inhSF.code, synSF.code with
  +                                | Lambda(ni, Lambda(si, inh)), Lambda(ns, Lambda(ss, syn)) ->
  +                                    let nf =
  +                                        if ni.Type.IsAssignableFrom ns.Type then ns
  +                                        elif ns.Type.IsAssignableFrom ni.Type then ni
  +                                        else failwith "[Ag] interface-inherit rules not implemented atm."
  +
  +                                    let rec inlineInh (e : Expr) =
  +                                        match e with
  +                                            | Let(cs, (Call(Some s, mi, [n]) as childScope), body) when mi.Name = "ChildScope" && typeof<Scope>.IsAssignableFrom mi.DeclaringType ->
  +                                                Expr.Let(
  +                                                    cs, inlineInh childScope,
  +                                                    Expr.Sequential(
  +                                                        Expr.FieldSet(Expr.Var cs, field, inh),
  +                                                        //Expr.Call(Expr.Var cs, scopeSet, [Expr.Value(inhIndex); Expr.Coerce(inh, typeof<obj>)]),
  +                                                        inlineInh body
  +                                                    )
  +                                                )
  +                                                
  +                                            | ShapeVar v ->
  +                                                if v = ns then Expr.Var nf
  +                                                elif v = ni then Expr.Var nf
  +                                                elif v = ss then Expr.Var si
  +                                                else e
  +                                            | ShapeLambda(v,b) ->
  +                                                Expr.Lambda(v, inlineInh b)
  +                                            | ShapeCombination(o, args) ->
  +                                                RebuildShapeCombination(o, args |> List.map inlineInh)
  +
  +                                    { synSF with 
  +                                        nodeType = nf.Type
  +                                        code = Expr.Lambda(nf, Expr.Lambda(si, inlineInh syn)) 
  +                                    }
  +
  +                                | _ ->
  +                                    failwith ""
  +                        )
  +
  +                    )
  +            }
  +
  +        let private compileNormal (sf : SemanticFunctions) =
  +            let strictInh =
  +                match sf.kind with
  +                    | AttributeKind.Synthesized ->
  +                        sf.functions
  +                            |> List.filter (fun sf ->Set.isEmpty sf.synthesizes)
  +                            |> List.map (fun sf -> sf.inherits)
  +                            |> Set.intersectMany
  +                    | _ ->
  +                        Set.empty
  +
  +            let inhIndices = strictInh |> Seq.mapi (fun i n -> (n,i)) |> Seq.toList
  +            let types = inhIndices |> List.map (fun (n,i) -> semanticFunctions.[n].valueType)
  +            let attributeIndices = strictInh |> Seq.map (fun n -> Globals.getAttributeIndex(n)) |> Seq.toList
  +            let strictInh = Map.ofList inhIndices
  +
  +            let scopeType = Scope.getType types
  +            let dispType = WrappedDispatcher.getType sf.valueType types
  +
  +            let dispType = dispType
  +            let selfDisp = Var(sprintf "self_%s" (Guid.NewGuid().ToString("N")), dispType)
  +
  +            let dispatcher =
  +                let mutable final = { sf with functions = sf.functions |> List.map (fun sf -> convert selfDisp scopeType strictInh sf) }
  +                for (KeyValue(s,_)) in strictInh do
  +                    let other = semanticFunctions.[s]
  +                    final <- addStrictInh selfDisp scopeType strictInh final other
  +
  +                let methods = 
  +                    final.functions |> List.choose (fun e ->
  +                        match e.code with
  +                            | Lambda(n,Lambda(s, body)) -> Some (sf.name, [n;Var(s.Name, scopeType)], fun _ -> body)
  +                            | _ -> None
  +                    )
  +
  +                let tModule = 
  +                    Compiler.compile {
  +                        Name = sf.name
  +                        Declarations =
  +                        [
  +                            Class {
  +                                Name = "Sem"
  +                                Arguments = [ selfDisp ]
  +                                BaseType = None
  +                                Fields = []
  +                                Members = methods
  +                            }
  +                        ]
  +                    }
  +
  +                let tSem = tModule.GetNestedType("Sem")
  +                let semCtor = tSem.GetConstructors().[0]
  +
  +                let mutable table = None
  +                let getTable (self : obj) =
  +                    match table with
  +                        | Some t -> t
  +                        | None ->
  +                            let instance = Activator.CreateInstance(tSem, self)
  +                            let methods = tSem.GetMethods(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.DeclaredOnly)
  +                            let t = 
  +                                MethodTable.ofList [
  +                                    for m in methods do
  +                                        yield instance, m
  +                                ]
  +                            table <- Some t
  +                            t
  +            
  +                let resolve (self : obj) (t : Type) =
  +                    self |> getTable |> MethodTable.tryResolve [| t; scopeType |]   
  +                            
  +                let tResolve = typeof<obj -> Type -> Option<obj * MethodInfo>>
  +                let tIndices = attributeIndices |> List.map (fun _ -> typeof<int>) |> List.toArray
  +                
  +
  +                let dispCtor = dispType.GetConstructor (Array.append tIndices [|tResolve|])
  +                let disp = dispCtor.Invoke (Array.append (List.toArray (List.map (fun a -> a :> obj) attributeIndices)) [|resolve|])
  +                
  +                disp |> unbox<IObjectDispatcher2>
  +
  +            dispatcher
  +
  +        let private compileRoot (attName : string) (valueType : Type) (methods : list<SemanticFunction>) =
  +            let td = typedefof<Dispatcher<_>>.MakeGenericType [| valueType |]
  +            let ctor = td.GetConstructor [| typeof<obj -> Type -> Option<obj * MethodInfo>> |]
  +            let realMethods =
  +                methods |> List.mapi (fun i sf ->
  +                    let mi = sf.original
  +                    if mi.IsGenericMethod then
  +                        failwith "[Ag] root rules must not be generic"
  +
  +                    let e = Expr.TryGetReflectedDefinition(mi) |> force "not possible"
  +                    let rec repair (e : Expr) =
  +                        match e with
  +                            | Scope -> failwith "[Ag] root rules must not use the current scope"
  +                            | Synthesize(name, node) -> failwith "[Ag] root rules must not synthesize attributes"
  +                            | Inherit(name) -> failwith "[Ag] root rules must not inherit attributes"
  +
  +                            | AssignInherit(value) ->
  +                                value
  +
  +                            | ShapeVar _ -> e
  +                            | ShapeLambda(v,b) -> Expr.Lambda(v, repair b)
  +                            | ShapeCombination(o, args) -> RebuildShapeCombination(o, args |> List.map repair)
  +
  +                    match repair (inlineSemTypes e) with
  +                        | Lambda(v,body) ->
  +                            let free = body.GetFreeVars() |> Set.ofSeq
  +                            let t = v.Type.GetGenericArguments().[0]
  +                            if Set.isEmpty free then 
  +                                attName, [Var(v.Name, t)], body
  +                            else 
                                   failwith "[Ag] root rule does not take an argument"
  -                    )
  -
  -                let instance,methods = QuotationCompiler.CreateInstance realMethods
  -
  -                let table = methods |> Array.map (fun mi -> instance,mi) |> MethodTable.ofArray
  -
  -                let resolve (self : obj) (t : Type) =
  -                    MethodTable.tryResolve [| t |] table
  -
  -                ctor.Invoke([|resolve|]) |> unbox<IObjectDispatcher>
  +                        | _ -> 
  +                            failwith "[Ag] root rule does not take an argument"
  +                )
  +
  +            let instance,methods = QuotationCompiler.CreateInstance realMethods
  +
  +            let table = methods |> Array.map (fun mi -> instance,mi) |> MethodTable.ofArray
  +
  +            let resolve (self : obj) (t : Type) =
  +                MethodTable.tryResolve [| t |] table
  +
  +            ctor.Invoke([|resolve|]) |> unbox<IObjectDispatcher>
   
           
   
  -            let compile (sf : SemanticFunctions) =
  -                if sf.kind = AttributeKind.Inherited then 
  -                    let root, other = sf.functions |> List.partition(fun f -> f.isRoot)
  -                    Globals.rootDispatchers.[sf.index] <- compileRoot sf.name sf.valueType root
  -                    Globals.inhDispatchers.[sf.index] <- compileNormal { sf with functions = other }
  -                else 
  -                    Globals.synDispatchers.[sf.index] <- compileNormal sf
  -
  -    open Implementation
  +        let compile (sf : SemanticFunctions) =
  +            if sf.kind = AttributeKind.Inherited then 
  +                let root, other = sf.functions |> List.partition(fun f -> f.isRoot)
  +                Globals.rootDispatchers.[sf.index] <- compileRoot sf.name sf.valueType root
  +                Globals.inhDispatchers.[sf.index] <- compileNormal { sf with functions = other }
  +            else 
  +                Globals.synDispatchers.[sf.index] <- compileNormal sf
  +
       let mutable private initialized = 0
       let init() =
           if System.Threading.Interlocked.Exchange(&initialized, 1) = 0 then
  
positive.code:             [<Attribute(AttributeKind.Synthesized)>]
              member x.All() : list<int> = x?All()
  
              [<Attribute(AttributeKind.Inherited)>]
              member x.Index : int = x?Index
  
              [<Attribute(AttributeKind.Inherited)>]
              member x.Bla : int = x?Bla
  
          [<Semantic>]
          type Sems =
  
negative.code: 
              static member Bla(c : Cons) =
                  inh <<= 10 + c.Bla
  
              static member Blubber(n : Nil) : int = 
                  bla().Inherit(Ag.Implementation.Globals.getAttributeIndex "Index")
  
              static member Blubber(c : Cons) : int = 
                  c.Tail.Blubber()
  
      [<Demo("Ag Demo")>]
      let run() =
          Ag.init()
          let all : obj -> list<int>  = Ag.getSynFunction "All"
          let sum : obj -> int        = Ag.getSynFunction "Sum"
          let blubber : obj -> int    = Ag.getSynFunction "Blubber"
          let list = Cons(0, Cons(1, Nil()))
          Log.line "sum [0;1] = %A" (sum list)
          Log.line "all [0;1] = %A" (all list)
  
          let scope = blubber list
          printfn "%A" scope
  
          
  
          if false then
  
              let rec long (n : int) =
                  if n = 0 then Nil() :> IList
  