func (heap *FibHeap) DecreaseKey(tag interface{}, key float64) error {
	if tag == nil {
		return errors.New("Input tag is nil ")
	}
	if math.IsInf(key, -1) {
		return errors.New("Negative infinity key is reserved for internal usage ")
	}
	if node, exists := heap.index[tag]; exists {
		return heap.decreaseKey(node, nil, key)
	}
	return errors.New("Value is not found ")
}
DecreaseKey updates the tag in the heap by the input key.
If the input key has a larger key or -inf key, an error will be returned.
If the input tag is not existed in the heap, an error will be returned.
DecreaseKey will check the nil interface but not the interface with nil value.
Try to input of an interface with nil value will cause invalid address panic.
package fibHeap
import (
	"bytes"
	"container/list"
	"errors"
	"fmt"
	"math"
)
type Value interface {
	Tag() interface{}
	Key() float64
}
type FibHeap struct {
	roots       *list.List
	index       map[interface{}]*node
	treeDegrees map[uint]*list.Element
	min         *node
	num         uint
}
type node struct {
	self     *list.Element
	parent   *node
	children *list.List
	marked   bool
	degree   uint
	position uint
	tag      interface{}
	key      float64
	value    Value
}
func NewFibHeap() *FibHeap {
	heap := new(FibHeap)
	heap.roots = list.New()
	heap.index = make(map[interface{}]*node)
	heap.treeDegrees = make(map[uint]*list.Element)
	heap.num = 0
	heap.min = nil
	return heap
}
func (heap *FibHeap) Num() uint {
	return heap.num
}
func (heap *FibHeap) Insert(tag interface{}, key float64) error {
	if tag == nil {
		return errors.New("Input tag is nil ")
	}
	return heap.insert(tag, key, nil)
}
func (heap *FibHeap) InsertValue(value Value) error {
	if value == nil {
		return errors.New("Input value is nil ")
	}
	return heap.insert(value.Tag(), value.Key(), value)
}
func (heap *FibHeap) Minimum() (interface{}, float64) {
	if heap.num == 0 {
		return nil, math.Inf(-1)
	}
	return heap.min.tag, heap.min.key
}
func (heap *FibHeap) MinimumValue() Value {
	if heap.num == 0 {
		return nil
	}
	return heap.min.value
}
func (heap *FibHeap) ExtractMin() (interface{}, float64) {
	if heap.num == 0 {
		return nil, math.Inf(-1)
	}
	min := heap.extractMin()
	return min.tag, min.key
}
func (heap *FibHeap) ExtractMinValue() Value {
	if heap.num == 0 {
		return nil
	}
	min := heap.extractMin()
	return min.value
}
func (heap *FibHeap) Union(anotherHeap *FibHeap) error {
	for tag := range anotherHeap.index {
		if _, exists := heap.index[tag]; exists {
			return errors.New("Duplicate tag is found in the target heap ")
		}
	}
	for _, node := range anotherHeap.index {
		heap.InsertValue(node.value)
	}
	return nil
}