Colorize elements from a POSet

Two elements from a POSet cannot have the same color if they share common subelements

Example:

      A
    / | \
   /  |  \
  B   C   D
  |  /|   |
  | / |   |
  |/  |   |
  E   F   G
  |
  H

Conflicts:

  • A: {B, C, D, E, F, G, H}
  • B: {A, C, E, H}
  • C: {A, E, H, F}
  • D: {A, G}
  • E: {A, B, C, H}
  • F: {A, C}
  • G: {A, D}
  • H: {A, B, C, E}

Possible colors:

  • A: 0
  • B: 1
  • C: 2
  • D: 1
  • E: 3
  • F: 3
  • G: 2
  • H: 4

SEE: Ducournau, R. (2011). Coloring, a versatile technique for implementing object-oriented languages. Software: Practice and Experience, 41(6), 627–659.

Introduced properties

private var _is_colored: Bool

nitc :: POSetColorer :: _is_colored

Is the poset already colored?
fun colorize(poset: POSet[E])

nitc :: POSetColorer :: colorize

Start coloring on given POSet
private fun colorize_core

nitc :: POSetColorer :: colorize_core

Core elements cannot have the same color than:
private fun colorize_set(set: Set[E])

nitc :: POSetColorer :: colorize_set

Other elements inherit color fron their direct parents
fun colors: Map[E, Int]

nitc :: POSetColorer :: colors

Resulting colors
private fun colors_cache=(colors_cache: HashMap[E, Int])

nitc :: POSetColorer :: colors_cache=

private fun compute_colors

nitc :: POSetColorer :: compute_colors

Colorize core, border and crown in that order
fun conflicts: Map[E, Set[E]]

nitc :: POSetColorer :: conflicts

REQUIRE: is_colored
private fun conflicts_cache=(conflicts_cache: Map[E, Set[E]])

nitc :: POSetColorer :: conflicts_cache=

private fun graph=(graph: POSetConflictGraph[E])

nitc :: POSetColorer :: graph=

fun ids: Map[E, Int]

nitc :: POSetColorer :: ids

Resulting ids
private fun ids_cache: HashMap[E, Int]

nitc :: POSetColorer :: ids_cache

private fun ids_cache=(ids_cache: HashMap[E, Int])

nitc :: POSetColorer :: ids_cache=

private fun is_color_free(color: Int, set: Collection[E]): Bool

nitc :: POSetColorer :: is_color_free

fun is_colored: Bool

nitc :: POSetColorer :: is_colored

Is the poset already colored?
protected fun is_colored=(is_colored: Bool)

nitc :: POSetColorer :: is_colored=

Is the poset already colored?
private fun min_color(e: E): Int

nitc :: POSetColorer :: min_color

Get the next minimal color from direct parents
fun poset: POSet[E]

nitc :: POSetColorer :: poset

REQUIRE: is_colored
private fun poset_cache=(poset_cache: POSet[E])

nitc :: POSetColorer :: poset_cache=

fun pretty_print

nitc :: POSetColorer :: pretty_print

Used for debugging only

Redefined properties

redef type SELF: POSetColorer[E]

nitc $ POSetColorer :: SELF

Type of this instance, automatically specialized in every class

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
private var _is_colored: Bool

nitc :: POSetColorer :: _is_colored

Is the poset already colored?
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
fun colorize(poset: POSet[E])

nitc :: POSetColorer :: colorize

Start coloring on given POSet
private fun colorize_core

nitc :: POSetColorer :: colorize_core

Core elements cannot have the same color than:
private fun colorize_set(set: Set[E])

nitc :: POSetColorer :: colorize_set

Other elements inherit color fron their direct parents
fun colors: Map[E, Int]

nitc :: POSetColorer :: colors

Resulting colors
private fun colors_cache=(colors_cache: HashMap[E, Int])

nitc :: POSetColorer :: colors_cache=

private fun compute_colors

nitc :: POSetColorer :: compute_colors

Colorize core, border and crown in that order
fun conflicts: Map[E, Set[E]]

nitc :: POSetColorer :: conflicts

REQUIRE: is_colored
private fun conflicts_cache=(conflicts_cache: Map[E, Set[E]])

nitc :: POSetColorer :: conflicts_cache=

fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
private fun graph=(graph: POSetConflictGraph[E])

nitc :: POSetColorer :: graph=

fun hash: Int

core :: Object :: hash

The hash code of the object.
fun ids: Map[E, Int]

nitc :: POSetColorer :: ids

Resulting ids
private fun ids_cache: HashMap[E, Int]

nitc :: POSetColorer :: ids_cache

private fun ids_cache=(ids_cache: HashMap[E, Int])

nitc :: POSetColorer :: ids_cache=

init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
private fun is_color_free(color: Int, set: Collection[E]): Bool

nitc :: POSetColorer :: is_color_free

fun is_colored: Bool

nitc :: POSetColorer :: is_colored

Is the poset already colored?
protected fun is_colored=(is_colored: Bool)

nitc :: POSetColorer :: is_colored=

Is the poset already colored?
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
private fun min_color(e: E): Int

nitc :: POSetColorer :: min_color

Get the next minimal color from direct parents
private intern fun native_class_name: CString

core :: Object :: native_class_name

The class name of the object in CString format.
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
fun poset: POSet[E]

nitc :: POSetColorer :: poset

REQUIRE: is_colored
private fun poset_cache=(poset_cache: POSet[E])

nitc :: POSetColorer :: poset_cache=

fun pretty_print

nitc :: POSetColorer :: pretty_print

Used for debugging only
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
package_diagram nitc::POSetColorer POSetColorer core::Object Object nitc::POSetColorer->core::Object

Parents

interface Object

core :: Object

The root of the class hierarchy.

Class definitions

nitc $ POSetColorer
# Colorize elements from a POSet
# Two elements from a POSet cannot have the same color if they share common subelements
#
# Example:
#
# ~~~raw
#       A
#     / | \
#    /  |  \
#   B   C   D
#   |  /|   |
#   | / |   |
#   |/  |   |
#   E   F   G
#   |
#   H
# ~~~
#
# Conflicts:
#
# * A: {B, C, D, E, F, G, H}
# * B: {A, C, E, H}
# * C: {A, E, H, F}
# * D: {A, G}
# * E: {A, B, C, H}
# * F: {A, C}
# * G: {A, D}
# * H: {A, B, C, E}
#
# Possible colors:
#
# * A: 0
# * B: 1
# * C: 2
# * D: 1
# * E: 3
# * F: 3
# * G: 2
# * H: 4
#
# SEE: Ducournau, R. (2011).
# Coloring, a versatile technique for implementing object-oriented languages.
# Software: Practice and Experience, 41(6), 627–659.
class POSetColorer[E: Object]

	# Is the poset already colored?
	var is_colored = false

	# Resulting ids
	#
	# All ids are strictly positive (`>= 1`).
	#
	# REQUIRE: is_colored
	fun ids: Map[E, Int] do
		assert is_colored
		return ids_cache
	end
	private var ids_cache = new HashMap[E, Int]

	# Resulting colors
	# REQUIRE: is_colored
	fun colors: Map[E, Int] do
		assert is_colored
		return colors_cache
	end
	private var colors_cache = new HashMap[E, Int]

	# REQUIRE: is_colored
	fun poset: POSet[E] do
		assert is_colored
		return poset_cache
	end
	private var poset_cache: POSet[E] is noinit

	# REQUIRE: is_colored
	fun conflicts: Map[E, Set[E]] do
		assert is_colored
		return conflicts_cache
	end
	private var conflicts_cache: Map[E, Set[E]] is noinit

	private var graph: POSetConflictGraph[E] is noinit

	# Start coloring on given POSet
	fun colorize(poset: POSet[E]) do
		poset_cache = poset
		graph = new POSetConflictGraph[E](poset)
		allocate_ids
		compute_colors
		conflicts_cache = graph.conflicts
		is_colored = true
	end

	private fun allocate_ids do
		ids_cache.clear
		var elements = new HashSet[E].from(poset_cache.to_a)
		for e in poset_cache.linearize(elements) do
			ids_cache[e] = ids_cache.length + 1
		end
	end

	# Colorize core, border and crown in that order
	private fun compute_colors do
		colors_cache.clear
		colorize_core
		colorize_set(graph.border)
		colorize_set(graph.crown)
	end

	# Core elements cannot have the same color than:
	#  * one of their parents
	#  * one of their conflicting elements
	private fun colorize_core do
		for e in poset_cache.linearize(graph.core) do
			var color = min_color(e)
			var conflicts = graph.conflicts[e]
			while not is_color_free(color, conflicts) do
				color += 1
			end
			colors_cache[e] = color
		end
	end

	# Other elements inherit color fron their direct parents
	private fun colorize_set(set: Set[E]) do
		for e in poset_cache.linearize(set) do colors_cache[e] = min_color(e)
	end

	# Get the next minimal color from direct parents
	private fun min_color(e: E): Int do
		var max_color = -1
		for p in poset_cache[e].direct_greaters do
			if not colors_cache.has_key(p) then continue
			var color = colors_cache[p]
			if color > max_color then max_color = color
		end
		return max_color + 1
	end

	private fun is_color_free(color: Int, set: Collection[E]): Bool do
		for e in set do
			if colors_cache.has_key(e) and colors_cache[e] == color then return false
		end
		return true
	end

	# Used for debugging only
	fun pretty_print do
		print "ids:"
		for e, id in ids do print "  {e}: {id}"
		print "colors:"
		for e, c in colors do print "  {e}: {c}"
	end
end
src/compiler/coloring.nit:132,1--285,3