Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add format check #36

Merged
merged 1 commit into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Configuration file for JuliaFormatter.jl
# For more information, see: https://domluna.github.io/JuliaFormatter.jl/stable/config/

always_for_in = true
always_use_return = true
margin = 80
remove_extra_newlines = true
separate_kwargs_with_semicolon = true
short_to_long_function_def = true
32 changes: 32 additions & 0 deletions .github/workflows/format_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
ame: format-check
on:
push:
branches:
- master
- release-*
pull_request:
types: [opened, synchronize, reopened]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: julia-actions/setup-julia@latest
with:
version: '1'
- uses: actions/checkout@v3
- name: Format check
shell: julia --color=yes {0}
run: |
using Pkg
# If you update the version, also update the style guide docs.
Pkg.add(PackageSpec(name="JuliaFormatter", version="1"))
using JuliaFormatter
format("src", verbose=true)
format("test", verbose=true)
out = String(read(Cmd(`git diff`)))
if isempty(out)
exit(0)
end
@error "Some files have not been formatted !!!"
write(stdout, out)
exit(1)
8 changes: 0 additions & 8 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,3 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
MultivariatePolynomials = "0.4.2"
MutableArithmetics = "0.3.1, 1"
julia = "1.6"

[extras]
DynamicPolynomials = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TypedPolynomials = "afbbf031-7a57-5f58-a1b9-b774a0fad08d"

[targets]
test = ["Test", "DynamicPolynomials", "TypedPolynomials"]
24 changes: 17 additions & 7 deletions src/SemialgebraicSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,24 @@ const MP = MultivariatePolynomials

const APL = AbstractPolynomialLike

export AbstractSemialgebraicSet, AbstractBasicSemialgebraicSet, AbstractAlgebraicSet
export FullSpace, AlgebraicSet, BasicSemialgebraicSet, addequality!, addinequality!
export AbstractSemialgebraicSet,
AbstractBasicSemialgebraicSet, AbstractAlgebraicSet
export FullSpace,
AlgebraicSet, BasicSemialgebraicSet, addequality!, addinequality!

# Semialgebraic set described by polynomials with coefficients in T
abstract type AbstractSemialgebraicSet end

abstract type AbstractBasicSemialgebraicSet <: AbstractSemialgebraicSet end
abstract type AbstractAlgebraicSet <: AbstractBasicSemialgebraicSet end

addinequality!(S::AbstractAlgebraicSet, p) = throw(ArgumentError("Cannot add inequality to an algebraic set"))

struct FullSpace <: AbstractAlgebraicSet
function addinequality!(S::AbstractAlgebraicSet, p)
throw(ArgumentError("Cannot add inequality to an algebraic set"))
end

struct FullSpace <: AbstractAlgebraicSet end
function Base.show(io::IO, ::FullSpace)
print(io, "R^n")
return print(io, "R^n")
end
nequalities(::FullSpace) = 0
equalities(::FullSpace) = []
Expand All @@ -39,7 +42,14 @@ Base.intersect(S::FullSpace, T::AbstractAlgebraicSet) = T
Base.intersect(S::FullSpace, T::FullSpace) = S

# If `intersect(S, T)` is not implemented, this method will `StackOverflow`.
Base.intersect(S::AbstractSemialgebraicSet, T::AbstractSemialgebraicSet, args...; kws...) = intersect(intersect(S, T), args...; kws...)
function Base.intersect(
S::AbstractSemialgebraicSet,
T::AbstractSemialgebraicSet,
args...;
kws...,
)
return intersect(intersect(S, T), args...; kws...)
end
# The keywords are only used when transforming `Element`
# into `BasicSemialgebraicSet`.
Base.intersect(set::AbstractSemialgebraicSet; kws...) = set
Expand Down
79 changes: 59 additions & 20 deletions src/basic.jl
Original file line number Diff line number Diff line change
@@ -1,55 +1,94 @@
export inequalities, basicsemialgebraicset

struct BasicSemialgebraicSet{T, PT<:APL{T}, AT <: AbstractAlgebraicSet} <: AbstractBasicSemialgebraicSet
struct BasicSemialgebraicSet{T,PT<:APL{T},AT<:AbstractAlgebraicSet} <:
AbstractBasicSemialgebraicSet
V::AT
p::Vector{PT}
end
function BasicSemialgebraicSet{T, PT}() where {T, PT<:APL{T}}
BasicSemialgebraicSet(AlgebraicSet{T, PT}(), PT[])
function BasicSemialgebraicSet{T,PT}() where {T,PT<:APL{T}}
return BasicSemialgebraicSet(AlgebraicSet{T,PT}(), PT[])
end
function BasicSemialgebraicSet(V::AlgebraicSet{T, PT, A, S}, p::Vector{PT}) where {T, PT<:APL{T}, A, S<:AbstractAlgebraicSolver}
BasicSemialgebraicSet{T, PT, typeof(V)}(V, p)
function BasicSemialgebraicSet(
V::AlgebraicSet{T,PT,A,S},
p::Vector{PT},
) where {T,PT<:APL{T},A,S<:AbstractAlgebraicSolver}
return BasicSemialgebraicSet{T,PT,typeof(V)}(V, p)
end
function BasicSemialgebraicSet(V::AlgebraicSet{T, PT, A, SO, U}, p::Vector{PS}) where {T, PT<:APL{T}, S, PS<:APL{S}, A, SO<:AbstractAlgebraicSolver, U}
function BasicSemialgebraicSet(
V::AlgebraicSet{T,PT,A,SO,U},
p::Vector{PS},
) where {T,PT<:APL{T},S,PS<:APL{S},A,SO<:AbstractAlgebraicSolver,U}
ST = promote_type(T, S)
PST = promote_type(PT, PS)
BasicSemialgebraicSet(convert(AlgebraicSet{ST, PST, A, SO, U}, V), Vector{PST}(p))
return BasicSemialgebraicSet(
convert(AlgebraicSet{ST,PST,A,SO,U}, V),
Vector{PST}(p),
)
end
#BasicSemialgebraicSet{T, PT<:APL{T}}(V::AlgebraicSet{T, PT}, p::Vector{PT}) = BasicSemialgebraicSet{T, PT}(V, p)
function basicsemialgebraicset(V, p)
BasicSemialgebraicSet(V, p)
return BasicSemialgebraicSet(V, p)
end

MP.similar_type(::Type{BasicSemialgebraicSet{S, PS, AT}}, T::Type) where {S, PS, AT} = BasicSemialgebraicSet{T, MP.similar_type(PS, T), MP.similar_type(AT, T)}
function MP.similar_type(
::Type{BasicSemialgebraicSet{S,PS,AT}},
T::Type,
) where {S,PS,AT}
return BasicSemialgebraicSet{
T,
MP.similar_type(PS, T),
MP.similar_type(AT, T),
}
end

function Base.convert(::Type{BasicSemialgebraicSet{T, PT, AT}}, set::BasicSemialgebraicSet) where {T, PT, AT}
return BasicSemialgebraicSet{T, PT, AT}(set.V, set.p)
function Base.convert(
::Type{BasicSemialgebraicSet{T,PT,AT}},
set::BasicSemialgebraicSet,
) where {T,PT,AT}
return BasicSemialgebraicSet{T,PT,AT}(set.V, set.p)
end

MP.variables(S::BasicSemialgebraicSet{T, PT, FullSpace}) where {T, PT<:APL{T}} = MP.variables(S.p)
MP.variables(S::BasicSemialgebraicSet) = sort(union(MP.variables(S.V), MP.variables(S.p)), rev=true)
function MP.variables(
S::BasicSemialgebraicSet{T,PT,FullSpace},
) where {T,PT<:APL{T}}
return MP.variables(S.p)
end
function MP.variables(S::BasicSemialgebraicSet)
return sort(union(MP.variables(S.V), MP.variables(S.p)); rev = true)
end
nequalities(S::BasicSemialgebraicSet) = nequalities(S.V)
equalities(S::BasicSemialgebraicSet) = equalities(S.V)
addequality!(S::BasicSemialgebraicSet, p) = addequality!(S.V, p)
ninequalities(S::BasicSemialgebraicSet) = length(S.p)
inequalities(S::BasicSemialgebraicSet) = S.p
addinequality!(S::BasicSemialgebraicSet, p) = push!(S.p, p)

Base.intersect(S::BasicSemialgebraicSet, T::BasicSemialgebraicSet) = BasicSemialgebraicSet(S.V ∩ T.V, [S.p; T.p])
Base.intersect(S::BasicSemialgebraicSet, T::AbstractAlgebraicSet) = BasicSemialgebraicSet(S.V ∩ T, copy(S.p))
function Base.intersect(S::BasicSemialgebraicSet, T::BasicSemialgebraicSet)
return BasicSemialgebraicSet(S.V ∩ T.V, [S.p; T.p])
end
function Base.intersect(S::BasicSemialgebraicSet, T::AbstractAlgebraicSet)
return BasicSemialgebraicSet(S.V ∩ T, copy(S.p))
end
Base.intersect(S::BasicSemialgebraicSet, ::FullSpace) = S
Base.intersect(T::AbstractAlgebraicSet, S::BasicSemialgebraicSet) = intersect(S, T)
function Base.intersect(T::AbstractAlgebraicSet, S::BasicSemialgebraicSet)
return intersect(S, T)
end

function Base.show(io::IO, V::BasicSemialgebraicSet)
print(io, "{ (", join(variables(V), ", "), ") | ",
join(string.(equalities(V)) .* " = 0", ", "))
print(
io,
"{ (",
join(variables(V), ", "),
") | ",
join(string.(equalities(V)) .* " = 0", ", "),
)
if nequalities(V) > 0
print(io, ", ")
end
print(io, join(string.(inequalities(V)) .* " ≥ 0", ", "), " }")
return print(io, join(string.(inequalities(V)) .* " ≥ 0", ", "), " }")
end
function Base.show(io::IO, mime::MIME"text/plain", V::BasicSemialgebraicSet)
print(io, "Basic semialgebraic Set defined by ")
_show_els(io, "equalit", nequalities(V), equalities(V), "=")
_show_els(io, "inequalit", ninequalities(V), inequalities(V), "≥")
return _show_els(io, "inequalit", ninequalities(V), inequalities(V), "≥")
end
83 changes: 57 additions & 26 deletions src/fix.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
export FixedVariablesSet

struct FixedVariablesIdeal{V<:AbstractVariable, T<:Number, MT<:AbstractMonomialLike} <: AbstractPolynomialIdeal
substitutions::Union{Nothing, Dict{V, T}}
end
function Base.convert(::Type{FixedVariablesIdeal{V, T, MT}}, ideal::FixedVariablesIdeal{V, T, MT}) where {V<:AbstractVariable, T<:Number, MT<:AbstractMonomialLike}
struct FixedVariablesIdeal{
V<:AbstractVariable,
T<:Number,
MT<:AbstractMonomialLike,
} <: AbstractPolynomialIdeal
substitutions::Union{Nothing,Dict{V,T}}
end
function Base.convert(
::Type{FixedVariablesIdeal{V,T,MT}},
ideal::FixedVariablesIdeal{V,T,MT},
) where {V<:AbstractVariable,T<:Number,MT<:AbstractMonomialLike}
return ideal
end
function Base.convert(::Type{FixedVariablesIdeal{V, T, MT}}, ideal::FixedVariablesIdeal{V, S, MT}) where {V, S, T, MT}
function Base.convert(
::Type{FixedVariablesIdeal{V,T,MT}},
ideal::FixedVariablesIdeal{V,S,MT},
) where {V,S,T,MT}
subs = ideal.substitutions
if subs !== nothing
subs = convert(Dict{V, T}, subs)
subs = convert(Dict{V,T}, subs)
end
return FixedVariablesIdeal{V, T, MT}(subs)
return FixedVariablesIdeal{V,T,MT}(subs)
end

function MP.variables(ideal::FixedVariablesIdeal{V}) where V
function MP.variables(ideal::FixedVariablesIdeal{V}) where {V}
if generate_nonzero_constant(ideal)
return V[]
else
return sort(collect(keys(ideal.substitutions)), rev=true)
return sort(collect(keys(ideal.substitutions)); rev = true)
end
end
# In that case, the ideal can generate any polynomial.
Expand All @@ -34,15 +44,26 @@ function Base.rem(p::AbstractPolynomialLike, I::FixedVariablesIdeal)
end
end

struct FixedVariablesSet{V, T, MT} <: AbstractAlgebraicSet
ideal::FixedVariablesIdeal{V, T, MT}
end
MP.similar_type(::Type{FixedVariablesSet{V, S, MT}}, T::Type) where {V, S, MT} = FixedVariablesSet{V, T, MT}
function Base.convert(::Type{FixedVariablesSet{V, T, MT}}, set::FixedVariablesSet{V, T, MT}) where {V, T, MT}
struct FixedVariablesSet{V,T,MT} <: AbstractAlgebraicSet
ideal::FixedVariablesIdeal{V,T,MT}
end
function MP.similar_type(
::Type{FixedVariablesSet{V,S,MT}},
T::Type,
) where {V,S,MT}
return FixedVariablesSet{V,T,MT}
end
function Base.convert(
::Type{FixedVariablesSet{V,T,MT}},
set::FixedVariablesSet{V,T,MT},
) where {V,T,MT}
return set
end
function Base.convert(::Type{FixedVariablesSet{V, T, MT}}, set::FixedVariablesSet{V, S, MT}) where {V, S, T, MT}
return FixedVariablesSet(convert(FixedVariablesIdeal{V, T, MT}, set.ideal))
function Base.convert(
::Type{FixedVariablesSet{V,T,MT}},
set::FixedVariablesSet{V,S,MT},
) where {V,S,T,MT}
return FixedVariablesSet(convert(FixedVariablesIdeal{V,T,MT}, set.ideal))
end

ideal(set::FixedVariablesSet, args...) = set.ideal
Expand All @@ -54,14 +75,17 @@ function nequalities(set::FixedVariablesSet)
return length(set.ideal.substitutions)
end
end
function equalities(set::FixedVariablesSet{V, T, MT}) where {V, T, MT}
function equalities(set::FixedVariablesSet{V,T,MT}) where {V,T,MT}
if set.ideal.substitutions === nothing
return [constant_term(one(T), MT)]
else
return [key - value for (key, value) in set.ideal.substitutions]
end
end
function Base.intersect(V::FixedVariablesSet{V1, T1, MT1}, W::FixedVariablesSet{V2, T2, MT2}) where {V1, V2, T1, T2, MT1, MT2}
function Base.intersect(
V::FixedVariablesSet{V1,T1,MT1},
W::FixedVariablesSet{V2,T2,MT2},
) where {V1,V2,T1,T2,MT1,MT2}
# For `DynamicPolynomials`, they have the same type and for
# `TypedPolynomials`, promoting would give `Monomial`.
VT = V1 == V2 ? V1 : AbstractVariable
Expand All @@ -76,14 +100,14 @@ function Base.intersect(V::FixedVariablesSet{V1, T1, MT1}, W::FixedVariablesSet{
end
return a
end
sub = Dict{VT, T}()
sub = Dict{VT,T}()
merge!(combine, sub, V.ideal.substitutions)
merge!(combine, sub, W.ideal.substitutions)
if has_dup
sub = nothing
end
end
ideal = FixedVariablesIdeal{VT, T, promote_type(MT1, MT2)}(sub)
ideal = FixedVariablesIdeal{VT,T,promote_type(MT1, MT2)}(sub)
return FixedVariablesSet(ideal)
end
function Base.intersect(V::AlgebraicSet, W::FixedVariablesSet)
Expand All @@ -103,12 +127,12 @@ end
# Assumes `isempty(V)`
function only_point(V::FixedVariablesSet)
subs = collect(V.ideal.substitutions)
sort!(subs, rev = true, by = sub -> sub[1])
sort!(subs; rev = true, by = sub -> sub[1])
return [sub[2] for sub in subs]
end

Base.eltype(::FixedVariablesSet{V, T}) where {V, T} = Vector{T}
function Base.iterate(V::FixedVariablesSet, state=nothing)
Base.eltype(::FixedVariablesSet{V,T}) where {V,T} = Vector{T}
function Base.iterate(V::FixedVariablesSet, state = nothing)
if state === nothing && !isempty(V)
return only_point(V), true
else
Expand All @@ -117,7 +141,7 @@ function Base.iterate(V::FixedVariablesSet, state=nothing)
end
Base.length(V::FixedVariablesSet) = isempty(V) ? 0 : 1

struct FixedVariable{V<:AbstractVariable, T}
struct FixedVariable{V<:AbstractVariable,T}
variable::V
value::T
end
Expand All @@ -130,6 +154,13 @@ end

function Base.intersect(el::FixedVariable; kws...)
subs = Dict(el.variable => el.value)
return FixedVariablesSet(FixedVariablesIdeal{
typeof(el.variable), typeof(el.value), typeof(el.variable)}(subs))
return FixedVariablesSet(
FixedVariablesIdeal{
typeof(el.variable),
typeof(el.value),
typeof(el.variable),
}(
subs,
),
)
end
Loading