Skip to content

Files

Latest commit

4458334 · Feb 17, 2025

History

History
653 lines (499 loc) · 18.4 KB

README.md

File metadata and controls

653 lines (499 loc) · 18.4 KB

go-subjectivelogic

This Go library implements a number of Subjective Logic operators. Subjective Logic is a type of probabilistic logic that uses subjective opinions instead of probabilities. To learn more about Subjective Logic please refer to "Subjective Logic, A Formalism for Reasoning under Uncertainty" book by Audun Jøsang.

Table of Contents

Usage

Opinion

Subjective Logic is a type of probabilistic logic that uses subjective opinions instead of probabilities. A binomial opinion about the truth of the proposition x is ω x = ( b x , d x , u x , a x ) , where:

  • b x : belief mass in support of the proposition x being true.
  • d x : disbelief mass in support of the proposition x being false.
  • u x : uncertainty mass representing lack of evidence.
  • a x : base rate i.e. the prior probability of x being true without any evidence.
type Opinion struct {
	belief      float64
	disbelief   float64
	uncertainty float64
	baseRate    float64
}

The following methods have been implemented for the opinion:

NewOpinion() method

The NewOpinion() method takes in four float64 values and outputs an Opinion as well as an Error. In case a valid Opinion can be formed, it will be returned and the error will be nil. If the input values violate the requirements for a valid Opinion, the Opinion would be initialized with zeroes and an error will be returned. For a valid Opinion, each input value i must fulfill 0 i 1 and the following statement b + d + u = 1 must hold.

opinion, err := subjectivelogic.NewOpinion(.5, .25, .25, .5)

if err != nil {
	println(err.Error())
} else {
	belief := opinion.GetBelief()
	disbelief := opinion.GetDisbelief()
	uncertainty := opinion.GetUncertainty()
	baseRate := opinion.GetBaseRate()
	
	println(fmt.Sprintf("Opinion: %.2f, %.2f, %.2f, %.2f", belief, disbelief, uncertainty, baseRate))
}

This code generates the following output:

Opinion: 0.50, 0.25, 0.25, 0.50

Addition

This implements the Addition Operator as defined in Subjective Logic:

ω ( x y ) = { b x y = b x + b y   d x y = a x ( d x b y ) + a y ( d y b x ) a x + a y   u x y = a x u x + a y u y a x + a y   a x y = 0

API Reference

func Addition(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

Inputs ω x = ( b x , d x , u x , a x ) and ω y = ( b y , d y , u y , a y ) are problematic and will result in an error, if:

b x + b y > 1 , or   a x + a y > 1

Moreover, the Addition Operator will attempt to divide through 0 , if a x = a y = 0 , hence this is not allowed and an error will be returned.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5)
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5) 
	opinion3, _ := subjectivelogic.NewOpinion(1, 0, 0, 0.5) 
	
	out1, err1 := subjectivelogic.Addition(&opinion1, &opinion2) //Case 1 
	out2, err2 := subjectivelogic.Addition(&opinion1, &opinion3) //Case 2 
	
	fmt.Println("Case 1:", "Opinion = ", out1.ToString(), "Error:", err1) 
	fmt.Println("Case 2:", "Opinion = ", out2.ToString(), "Error:", err2) 

}

The above code snippet shows the usage of the Addition operator. Case 1 uses two Opinions that are not problematic for the Addition operator, resulting in a valid output Opinion and no error:

Case 1: Opinion =  0.6000000000000001, 0.1, 0.3, 1 Error: <nil>

Case 2 uses two valid Opinions that are problematic for the Addition operator as the sum of their belief masses exceeds 1 . This results in the Addition operator returning a zeroed Opinion and an error.

Case 2: Opinion =  0, 0, 0, 0 Error: Addition: Check the validity of your input values

Complement

This implements the Complement Operator as defined in Subjective Logic:

ω x : { b x = d x   d x = b x   u x = u x   a x = 1 a x

API Reference

func Complement(opinion *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	
	out, err := subjectivelogic.Complement(&opinion) 

	if err != nil { 
		fmt.Println("Error:", err) 
	} else { 
		fmt.Println("Output:", out, err) 
	}
}

The code snippet above shows the usage of the Complement operator. This specific example will result in the following output:

Output: {0.8 0.2 0 0.5} <nil>

Binomial Multiplication

This implements the Binomial Multiplication Operator as defined in Subjective Logic:

ω x y : { b x y = b x b y + ( 1 a x ) a y b x u y + a x ( 1 a y ) b y u x 1 a x a y   d x y = d x + d y d x d y   u x y = u x u y + ( 1 a y ) b x u y + ( 1 a x ) u x b y 1 a x a y   a x y = a x a y

API Reference

func Multiplication(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

The Binomial Multiplication Operator will try to divide through 0 , if a x = a y = 1 , hence this is not allowed and an error is returned.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5)
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5) 

	out, err := subjectivelogic.Multiplication(&opinion1, &opinion2)

	if err != nil { 
		fmt.PrintlnImplementation("Error:", err)
	} else {
		fmt.Println("Output:", out, err) 
	}	
}

The code snippet above shows the usage of the Multiplication operator. This specific example will result in the following output:

Output: {0.12000000000000002 0.8 0.08 0.25} <nil>

Binomial Comultiplication

This implements the Comultiplication Operator as defined in Subjective Logic:

ω x y : { b x y = b x + b y b x b y   d x y = d x d y + a x ( 1 a y ) d x u y + ( 1 a x ) a y u x d y a x + a y a x a y   u x y = u x u y + a y d x u y + a x u x d y a x + a y a x a y   a x y = a x + a y a x a y

API Reference

func Comultiplication(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

The Binomial Comultiplication Operator will try to divide through 0 , if a x = a y = 0 , hence this is not allowed and an error will be returned.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5)
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.Comultiplication(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Comultiplication operator. This specific example will result in the following output:

Output: {0.52 0.16 0.32 0.75} <nil>

Belief Constraint Fusion

==This implements the Belief Constraint Fusion Operator as defined in Subjective Logic:==

NEEDS TO BE EDITED

ω X ( A & B ) : { b X ( A & B ) = b X A u X B + b X B u X A + b X A b X B 1 C o n   d X ( A & B ) = d X A u X B + d X B u X A + d X A d X B 1 C o n   u X ( A & B ) = u X A u X B 1 C o n   a X ( A & B ) = a X A ( 1 u X A ) + a X B ( 1 u X B ) 2 u X A u X B for u X A + u X B < 2   a X ( A & B ) = a X A + a X B 2 for u X A = u X B = 1 C o n = b X A d X B + d X A b X B

API Reference

func ConstraintFusion(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

The Belief Constraint Fusion Operator will try to divide through 0 , if the conflict variable C o n = 1 , and an error will be returned.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.ConstraintFusion(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Belief Constraint operator. This specific example will result in the following output:

Output: {0.2941176470588236 0.7058823529411764 0 0.5} <nil>

Cumulative Fusion

This implements the Aleatory Cumulative Fusion Operator as defined in Subjective Logic:

Case I: For u X A 0 u X B 0 :

ω X ( A B ) : { b X ( A B ) ( x ) = b X A ( x ) u X B + b X B ( x ) u X A u X A + u X B u X A u X B   u X ( A B ) = u X A u X B u X A + u X B u X A u X B   a X ( A B ) ( x ) = a X A ( x ) u X B + a X B ( x ) u X A ( a X A ( x ) + a X B ( x ) ) u X B u X A u X A + u X B 2 u X A u X B if u X A 1 u X B 1   a X ( A B ) ( x ) = a X A ( x ) + a X B ( x ) 2 if u X A = u X B = 1

Case II: For u X A = u X B = 0 :

ω X ( A B ) : { b X ( A B ) ( x ) = γ X A b X A ( x ) + γ X B b X B ( x )   u X ( A B ) = 0   a X ( A B ) ( x ) = γ X A a X A ( x ) + γ X B a X B ( x ) where γ X A = γ X B = 0.5

API Reference

func CumulativeFusion(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.CumulativeFusion(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Cumulative fusion operator. This specific example will result in the following output:

Output: {0.2 0.8 0 0.5} <nil>

Averaging Fusion

This implements the Averaging Fusion Operator as defined in Subjective Logic:

Case I: For u X A 0 u X B 0 :

ω X ( A B ) : { b X ( A B ) ( x ) = b X A ( x ) u X B + b X B ( x ) u X A u X A + u X B   u X ( A B ) = 2 u X A u X B u X A + u X B   a X ( A B ) ( x ) = a X A ( x ) + a X B ( x ) 2

Case II: For u X A = u X B = 0 :

ω X ( A B ) : { b X ( A B ) ( x ) = γ X A b X A ( x ) + γ X B b X B ( x )   u X ( A B ) = 0   a X ( A B ) ( x ) = γ X A a X A ( x ) + γ X B a X B ( x ) where γ X A = γ X B = 0.5

API Reference

func AveragingFusion(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.AveragingFusion(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Averaging fusion operator. This specific example will result in the following output:

Output: {0.2 0.8 0 0.5} <nil>

Weighted Fusion

This implements the Weighted Fusion Operator as defined in Subjective Logic:

Case I: For ( u X A 0 u X B 0 ) ( u X A 1 u X B 1 ) :

ω X ( A B ) : { b X ( A B ) ( x ) = b X A ( x ) ( 1 u X A ) u X B + b X B ( x ) ( 1 u X B ) u X A u X A + u X B 2 u X A u X B   u X ( A B ) = ( 2 u X A u X B ) u X A u X B u X A + u X B 2 u X A u X B   a X ( A B ) ( x ) = a X A ( x ) ( 1 u X A ) + a X B ( x ) ( 1 u X B ) 2 u X A u X B

Case II: For u X A = u X B = 0 :

ω X ( A B ) : { b X ( A B ) ( x ) = γ X A b X A ( x ) + γ X B b X B ( x )   u X ( A B ) = 0   a X ( A B ) ( x ) = γ X A a X A ( x ) + γ X B a X B ( x ) where γ X A = γ X B = 0.5

Case III: u X A = u X B = 1 :

ω X ( A B ) : { b X ( A B ) ( x ) = 0   u X ( A B ) = 1   a X ( A B ) ( x ) = a X A ( x ) + a X B ( x ) 2

API Reference

func WeightedFusion(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.WeightedFusion(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Weighted fusion operator. This specific example will result in the following output:

Output: {0.2 0.8 0 0.5} <nil>

Trust Discounting

This implements the Trust Discounting Operator as defined in Subjective Logic:

ω X [ A ; B ] : { b X [ A ; B ] ( x ) = P B A b X B ( x )   u X [ A ; B ] = 1 P B A x R ( X ) b X B ( x )   a X [ A ; B ] ( x ) = a X B ( x )  

API Reference

func TrustDiscounting(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(0.4, 0, 0.6, 0.5)

	out, err := subjectivelogic.TrustDiscounting(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Trust discounting operator. This specific example will result in the following output:

Output: {0.08000000000000002 0 0.9199999999999999 0.5} <nil>

Trust Discounting for Multi-edge Path

This implements the Trust Discounting Operator for Multi-edge Paths as defined in Subjective Logic.

If [ A 1 , . . . , A n ] denotes the referral trust path and [ A n , X ] the functional trust, the Trust Discounting Operator for multi-edge paths is defined as:

ω X A 1 : { b X A 1 ( x ) = P A n A 1 b X A n ( x )   u X A 1 = 1 P A n A 1 x X b X A n ( x )   a X A 1 ( x ) = a X A n ( x )

and:

P A n A 1 = i = 1 n 1 P A i + 1 A i

API Reference

TBD

Problematic Inputs

TBD

Example

TBD

Opposite-Belief Trust Discounting

This implements the Opposite-Belief Trust Discounting Operator as defined in Subjective Logic:

ω X [ A ; B ] : { b X [ A ; B ] = b B A b X B + d B A d X B   d X [ A ; B ] = b B A d X B + d B A b X B   u X [ A ; B ] = u B A + ( b B A + d B A ) u X B   a X [ A ; B ] = a X B  

API Reference

func TrustDiscountingOB(opinion1 *Opinion, opinion2 *Opinion) (Opinion, error)

Problematic Inputs

There are no problematic inputs for this operator, as long as they are valid opinions.

Example

func main() {

	opinion1, _ := subjectivelogic.NewOpinion(0.2, 0.8, 0, 0.5) 
	opinion2, _ := subjectivelogic.NewOpinion(1, 0, 0, 0.5)

	out, err := subjectivelogic.TrustDiscountingOB(&opinion1, &opinion2)

	if err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println("Output:", out, err)
	}
}

The code snippet above shows the usage of the Trust discounting operator. This specific example will result in the following output:

Output: {0.2 0.8 0 0.5} <nil>

Contributing

Contributions are very welcome! Please let us know if you find an issue and have ideas for improvement. Alternately, open an issue or submit a pull request on GitHub.

License

This project is licensed under the Apache License, Verion 2.0 - see the LICENSE file for details.

Contact

In case of problems or issues, please open an issue on GitHub.