Compare commits

..

No commits in common. "65d23fb6676c73aad5817941c94d75573b6e4d10" and "0731c7aac18fee58daa0675e84eb065c029984d7" have entirely different histories.

2 changed files with 23 additions and 38 deletions

View File

@ -1,5 +1,3 @@
include("HittingSet.jl")
module Engine
export Construction, mprod
@ -8,24 +6,6 @@ import Subscripts
using LinearAlgebra
using AbstractAlgebra
using Groebner
using ..HittingSet
# --- commutative algebra ---
# as of version 0.36.6, AbstractAlgebra only supports ideals in multivariate
# polynomial rings when the coefficients are integers. we use Groebner to extend
# support to rationals and to finite fields of prime order
Generic.reduce_gens(I::Generic.Ideal{U}) where {T <: FieldElement, U <: MPolyRingElem{T}} =
Generic.Ideal{U}(base_ring(I), groebner(gens(I)))
function codimension(I::Generic.Ideal{U}, maxdepth = Inf) where {T <: RingElement, U <: MPolyRingElem{T}}
leading = [exponent_vector(f, 1) for f in gens(I)]
targets = [Set(findall(.!iszero.(exp_vec))) for exp_vec in leading]
length(HittingSet.solve(HittingSetProblem(targets), maxdepth))
end
dimension(I::Generic.Ideal{U}, maxdepth = Inf) where {T <: RingElement, U <: MPolyRingElem{T}} =
length(gens(base_ring(I))) - codimension(I, maxdepth)
# --- primitve elements ---
@ -43,6 +23,8 @@ mutable struct Point{T} <: Element{T}
) where T = new(coords, vec, nothing)
end
##coordnames(_::Point) = [:xₚ, :yₚ, :zₚ]
function buildvec!(pt::Point)
coordring = parent(pt.coords[1])
pt.vec = [one(coordring), dot(pt.coords, pt.coords), pt.coords...]
@ -61,6 +43,8 @@ mutable struct Sphere{T} <: Element{T}
) where T = new(coords, vec, rel)
end
##coordnames(_::Sphere) = [:rₛ, :sₛ, :xₛ, :yₛ, :zₛ]
function buildvec!(sph::Sphere)
coordring = parent(sph.coords[1])
sph.vec = sph.coords
@ -146,6 +130,10 @@ function realize(ctx::Construction{T}) where T
end
end
display(collect(elemenum))
display(coordnamelist)
println()
# construct coordinate ring
coordring, coordqueue = polynomial_ring(parent_type(T)(), coordnamelist, ordering = :degrevlex)
@ -162,14 +150,16 @@ function realize(ctx::Construction{T}) where T
# construct coordinate vectors
for (_, elem) in elemenum
buildvec!(elem)
display(elem.coords)
display(elem.vec)
println()
end
# turn relations into equations
eqns = vcat(
vcat(
equation.(ctx.relations),
[elem.rel for elem in ctx.elements if !isnothing(elem.rel)]
)
Generic.Ideal(coordring, eqns)
end
end
@ -182,26 +172,22 @@ a = Engine.Point{CoeffType}()
s = Engine.Sphere{CoeffType}()
a_on_s = Engine.LiesOn{CoeffType}(a, s)
ctx = Engine.Construction{CoeffType}(elements = Set([a]), relations= Set([a_on_s]))
ideal_a_s = Engine.realize(ctx)
println("A point on a sphere: ", Engine.dimension(ideal_a_s), " degrees of freeom")
eqns_a_s = Engine.realize(ctx)
b = Engine.Point{CoeffType}()
b_on_s = Engine.LiesOn{CoeffType}(b, s)
Engine.push!(ctx, b)
Engine.push!(ctx, s)
Engine.push!(ctx, b_on_s)
ideal_ab_s = Engine.realize(ctx)
println("Two points on a sphere: ", Engine.dimension(ideal_ab_s), " degrees of freeom")
eqns_ab_s = Engine.realize(ctx)
spheres = [Engine.Sphere{CoeffType}() for _ in 1:3]
tangencies = [
Engine.AlignsWithBy{CoeffType}(
spheres[n],
spheres[mod1(n+1, length(spheres))],
CoeffType(-1//1)
-1//1
)
for n in 1:3
]
ctx_tan_sph = Engine.Construction{CoeffType}(elements = Set(spheres), relations = Set(tangencies))
ideal_tan_sph = Engine.realize(ctx_tan_sph)
println("Three mutually tangent spheres: ", Engine.dimension(ideal_tan_sph), " degrees of freeom")
ctx_chain = Engine.Construction{CoeffType}(elements = Set(spheres), relations = Set(tangencies))

View File

@ -1,15 +1,13 @@
module HittingSet
export HittingSetProblem, solve
HittingSetProblem{T} = Pair{Set{T}, Vector{Pair{T, Set{Set{T}}}}}
# `targets` should be a collection of Set objects
function HittingSetProblem(targets, chosen = Set())
wholeset = union(targets...)
# `subsets` should be a collection of Set objects
function HittingSetProblem(subsets, chosen = Set())
wholeset = union(subsets...)
T = eltype(wholeset)
unsorted_moves = [
elt => Set(filter(s -> elt s, targets))
elt => Set(filter(s -> elt s, subsets))
for elt in wholeset
]
moves = sort(unsorted_moves, by = pair -> length(pair.second))
@ -34,6 +32,7 @@ end
function solve(pblm::HittingSetProblem{T}, maxdepth = Inf) where T
problems = Dict(pblm)
println(typeof(problems))
while length(first(problems).first) < maxdepth
subproblems = typeof(problems)()
for (chosen, moves) in problems
@ -57,7 +56,7 @@ end
function test(n = 1)
T = [Int64, Int64, Symbol, Symbol][n]
targets = Set{T}.([
subsets = Set{T}.([
[
[1, 3, 5],
[2, 3, 4],
@ -99,7 +98,7 @@ function test(n = 1)
[:b, :z, :t14]
]
][n])
problem = HittingSetProblem(targets)
problem = HittingSetProblem(subsets)
if isa(problem, HittingSetProblem{T})
println("Correct type")
else