This simple beginning doesn’t yet add very much to previous versions. In fact, it's a temporary step back before hopefully moving forward again. I post it now in case the enhancements are delayed. A few of things that I should point out are:

1) This version adds the concept of proven certainty vs. estimated certainty. This will facilitate later enhancements using estimated results to order queries, etc.

2) I have temporarily removed the idea of short circuiting on anything less than the most extreme certainties (Impossible, Certain). This will be re-added later.

3) I have temporarily removed the ability to continue searching on a disjunction until the most certain hypothesis is proven; it now stops on the first hypothesis proven. This will be re-added later.

4) I added back the ability to query the user for a Boolean.

As always, there is no exhaustive quality control on this; use it at your own risk.

`open System`

///<summary>Query helper.</summary>

let internal GetBoolean q =

printf "%s " q

let key = Console.ReadKey().KeyChar

printfn ""

(key='y')||(key='t')|| (key='Y')||(key='T')

///<summary>Degree of certainty.</summary>

type Certainty =

| Impossible = 0

| Disproven = 1

| Unlikely = 2

| Possible = 3

| Likely = 4

| Proven = 5

| Certain = 6

///<summary>Minimum (Certainty).</summary>

let Min c0 c1 =

match (c0<c1) with

| true -> c0

| false -> c1

///<summary>Maximum (Certainty).</summary>

let Max c0 c1 =

match (c0>c1) with

| true -> c0

| false -> c1

///<summary>Nature of the proof.</summary>

type Proof =

| Estimated = 0

| Known = 1

///<summary>Evidence for an hypothesis.</summary>

type Evidence = {

Certainty : Certainty;

Proof : Proof; }

///<summary>Most certain evidence.</summary>

let MostCertain e0 e1 =

match (e0.Certainty>=e1.Certainty) with

| true -> e0

| false -> e1

///<summary>Returns the best of two evidences.</summary>

let Best e0 e1 =

match e0.Proof with

| Proof.Known ->

match e1.Proof with

| Proof.Known -> MostCertain e0 e1

| _ -> e0

| _ ->

match e1.Proof with

| Proof.Known -> e1

| _ -> MostCertain e0 e1

///<summary>Hypothesis base.</summary>

[<AbstractClass>]

type Hypothesis (name:string) =

let mutable evidence = {

Certainty=Certainty.Impossible;

Proof=Proof.Estimated }

member this.Name = name

member this.Evidence = evidence

member this.Certainty

with get() = evidence.Certainty

and set c = evidence <- { Certainty=c;

Proof=Proof.Known }

member this.Proof with get() = evidence.Proof

abstract Prove : unit->Evidence

///<summary>A constant fact.</summary>

type Fact (name:string,

certainty:Certainty) =

inherit Hypothesis (name)

do (base.Certainty<-certainty)

override this.Prove () = base.Evidence

///<summary>A boolean-queried fact.</summary>

type QueryBoolean (name:string,

query:string) =

inherit Hypothesis (name)

override this.Prove () =

match base.Evidence.Proof with

| Proof.Known -> base.Evidence

| _ ->

base.Certainty <-

match GetBoolean(query) with

| true -> Certainty.Certain

| false -> Certainty.Impossible

base.Evidence

///<summary>Compound hypothesis.</summary>

[<AbstractClass>]

type HypothesisCompound (name:string,

antecedents:Hypothesis list) =

inherit Hypothesis (name)

///<summary>Conjunctive hypothesis.</summary>

type Conjunction (name:string,

antecedents:Hypothesis list) =

inherit HypothesisCompound (name,

antecedents)

member private this.prove (l:Hypothesis list) =

match l with

| [] -> Certainty.Certain

| h::[] -> h.Prove().Certainty

| h::t ->

match h.Prove().Certainty with

| Certainty.Impossible -> Certainty.Impossible

| c -> Min c (this.prove(t))

override this.Prove () =

match base.Evidence.Proof with

| Proof.Known -> base.Evidence

| _ ->

base.Certainty <- this.prove antecedents

base.Evidence

///<summary>Disjunctive hypothesis.</summary>

type Disjunction (name:string,

antecedents:Hypothesis list) =

inherit HypothesisCompound (name,

antecedents)

member private this.prove (l:Hypothesis list) =

match l with

| [] -> Certainty.Certain

| h::[] -> h.Prove().Certainty

| h::t ->

match h.Prove().Certainty with

| Certainty.Certain -> Certainty.Certain

| c -> Max c (this.prove(t))

override this.Prove () =

match base.Evidence.Proof with

| Proof.Known -> base.Evidence

| _ ->

base.Certainty <- this.prove antecedents

base.Evidence

// Tests.

let f0 = Fact("f0", Certainty.Certain)

let f1 = Fact("f1", Certainty.Certain)

let f2 = Fact("f2", Certainty.Certain)

let q0 = QueryBoolean("q0", "Is it q0?")

let q1 = QueryBoolean("q1", "Is it q1?")

let q2 = QueryBoolean("q2", "Is it q2?")

let c0 = Conjunction("c0", [ f0; q0 ])

let c1 = Conjunction("c1", [ f1; q1 ])

let c2 = Conjunction("c2", [ f2; q2 ])

let c01 = Conjunction("c01", [ c0; c1 ])

let d0 = Disjunction("d0", [ c01; c2 ])

let x0 = d0.Prove()

printfn "%s %s"

(x0.Certainty.ToString())

(x0.Proof.ToString())

Console.ReadLine() |> ignore

## No comments:

Post a Comment