using Pkg
Pkg.activate("metacat")
Pkg.add(url="git@github.com:AlgebraicJulia/Catlab.jl.git")
Pkg.add(url="https://github.com/0x0f0f0f/Metatheory.jl.git")
using Metatheory
using Metatheory.EGraphs
using Catlab
using Catlab.Theories
function convert_types(types)
ret = []
for typ in types
for accessor in typ.params
lhs = Expr(:call, accessor, Expr(:call , :type, Expr(:call, typ.name, hom.params... )))
push!(ret, :( $lhs => $accessor ))
end
end
return ret
end
symbols(e::Expr) = length(e.args) > 1 ? reduce(union, symbols.(e.args[2:end]) ) : Set([])
symbols(s::Symbol) = Set([s])
find_field(typ::Expr, a) = findfirst(x -> x == a, typ.args[2:end])
find_field(typ::Symbol, a) = nothing
function find_context(context, a)
for (f,typ) in context
i = find_field(typ,a)
if i != nothing
return (f,typ,i)
end
end
end
find_field(:(Hom(A,B)), :C)
find_context(Dict(:f => :(Hom(A,B))), :A)
function build_type_finder(ctx, u) # builds functional form of extractor from context.
ident, typ, pos = find_context(ctx, u)
u => :(proj($pos, type($ident )))
end
type_finder_dict(ctx, unknowns) = Dict([ build_type_finder(ctx, u) for u in unknowns])
replace(e::Symbol, ud) = begin
#println(e)
haskey(ud,e) ? ( ud[e]) : e
end
replace(e::Expr, unknown_replace_dict) = begin
Expr(e.head, e.args[1], [ replace(a, unknown_replace_dict) for a in e.args[2:end] ]... ) end
function type_terms(terms)
ret = []
for term in terms
lhs = Expr(:call , :type, Expr(:call, term.name, term.params... ))
known = Set(term.params)
unknowns = setdiff(symbols(term.typ) , known)
unknown_replace_dict = type_finder_dict(term.context, unknowns)
builtterm = replace(term.typ, unknown_replace_dict)
#println(unknown_replace_dict)
#println(builtterm)
#=
typ_map = Dict()
while !isempty(unknowns)
u = pop!(unknowns)
push!(known, u)
type_u = term.context[u]
typ_map[u] = type_u
unknowns = unknowns ∪ (setdiff(symbols(type_u) , known ))
end
println(typ_map)
=#
push!(ret, :( $lhs => $(builtterm)))
end
return ret
end
type_terms( theory(Category).terms )
# If we want to go with the accessor encoding, We need to lookup parameters on the right hand side
# I should possible use metatheory to do replacement
# should I make these function singular and just map them?
function convert_axioms(axioms)
ret = []
for axiom in axioms
#lhs = Expr(:call , :type, Expr(:call, term.name, term.params... ))
#println(axiom)
leftsyms = symbols(axiom.left)
rightsyms = symbols(axiom.right)
# left to right
unknowns = setdiff(rightsyms, leftsyms)
#println(unknowns)
#println([ find_context(axiom.context, u) for u in unknowns])
d = type_finder_dict(axiom.context, unknowns)
newright = replace(axiom.right, d)
push!(ret, :( $(axiom.left) => $(newright)))
unknowns = setdiff(leftsyms, rightsyms)
d = type_finder_dict(axiom.context, unknowns)
newleft = replace(axiom.left, d)
push!(ret, :( $(axiom.right) => $(newleft)))
end
return ret
end
#convert_axioms( theory(Category).axioms)
convert_axioms( theory(MonoidalCategory).axioms)
#theory(MonoidalCategory).axioms
function find_term(termcons, n)
for termcon in termcons
if termcon.name == n
return termcon
end
end
end
function typing_equuations(theory,s::Symbol)
return []
end
function typing_equations(theory, e::Expr)
@assert e.head == :call
name = e.args[1]
term_con = find_term(theory.terms, name)
println(e)
#freshparams = [p => gensym(p) for p in term_con.params ]
#rec_equations = [ kv[2] => a for (kv,a) in zip(freshparams, e.args[2:end]) ]
rec_equations = [k => v for (k,v) in zip(term_con.params, e.args[2:end])]
r2 = [ replace( k, Dict(rec_equations)) => replace( v, Dict(rec_equations)) for (k,v) in term_con.context]
r3 = [ typing_equations(theory, a) for a in e.args[2:end] ]
return vcat(r2,r3)
end
typing_equations( theory(MonoidalCategory), :(otimes(f,id(a))) )