├── .gitignore ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── .travis.yml ├── Examples ├── bdd.fsx ├── combining.fsx ├── completion.fsx ├── complex.fsx ├── cong.fsx ├── cooper.fsx ├── decidable.fsx ├── defcnf.fsx ├── dp.fsx ├── eqelim.fsx ├── equal.fsx ├── fol.fsx ├── folderived.fsx ├── geom.fsx ├── grobner.fsx ├── herbrand.fsx ├── init_all.fsx ├── initialization.fsx ├── interpolation.fsx ├── intro.fsx ├── lcffol.fsx ├── lcfprop.fsx ├── lib.fsx ├── limitations.fsx ├── meson.fsx ├── order.fsx ├── paramodulation.fsx ├── prolog.fsx ├── prop.fsx ├── propexamples.fsx ├── qelim.fsx ├── real.fsx ├── resolution.fsx ├── rewrite.fsx ├── skolem.fsx ├── skolems.fsx ├── stal.fsx ├── tableaux.fsx ├── tactics.fsx └── unif.fsx ├── FSharpx.Books.AutomatedReasoning.Tests ├── FSharpx.Books.AutomatedReasoning.Tests.VS10.fsproj ├── FSharpx.Books.AutomatedReasoning.Tests.VS11.fsproj ├── Option.fs ├── app.config ├── bdd.fs ├── combining.fs ├── completion.fs ├── complex.fs ├── cong.fs ├── cooper.fs ├── decidable.fs ├── defcnf.fs ├── dp.fs ├── eqelim.fs ├── equal.fs ├── fol.fs ├── folderived.fs ├── geom.fs ├── grobner.fs ├── herbrand.fs ├── interpolation.fs ├── intro.fs ├── lcffol.fs ├── lcfprop.fs ├── lib.fs ├── limitations.fs ├── meson.fs ├── order.fs ├── packages.config ├── paramodulation.fs ├── prolog.fs ├── prop.fs ├── propexamples.fs ├── qelim.fs ├── real.fs ├── resolution.fs ├── rewrite.fs ├── skolem.fs ├── skolems.fs ├── stal.fs ├── tableaux.fs ├── tactics.fs └── unif.fs ├── FSharpx.Books.AutomatedReasoning.VS10.sln ├── FSharpx.Books.AutomatedReasoning.VS11.sln ├── FSharpx.Books.AutomatedReasoning ├── FSharpx.Books.AutomatedReasoning.VS10.fsproj ├── FSharpx.Books.AutomatedReasoning.VS11.fsproj ├── bdd.fs ├── combining.fs ├── completion.fs ├── complex.fs ├── cong.fs ├── cooper.fs ├── decidable.fs ├── defcnf.fs ├── dp.fs ├── eqelim.fs ├── equal.fs ├── fol.fs ├── folderived.fs ├── formulas.fs ├── geom.fs ├── grobner.fs ├── herbrand.fs ├── initialization.fs ├── interpolation.fs ├── intro.fs ├── lcf.fs ├── lcffol.fs ├── lcfprop.fs ├── lib.fs ├── limitations.fs ├── meson.fs ├── order.fs ├── packages.config ├── paramodulation.fs ├── prolog.fs ├── prop.fs ├── propexamples.fs ├── qelim.fs ├── real.fs ├── resolution.fs ├── rewrite.fs ├── skolem.fs ├── skolems.fs ├── stal.fs ├── tableaux.fs ├── tactics.fs └── unif.fs ├── LICENSE.txt ├── OCaml Results.pdf ├── packages └── repositories.config └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | # Visual Studio files 6 | *.[Oo]bj 7 | *.exe 8 | *.pdb 9 | *.user 10 | *.aps 11 | *.pch 12 | *.vspscc 13 | *.vssscc 14 | *_i.c 15 | *_p.c 16 | *.ncb 17 | *.suo 18 | *.tlb 19 | *.tlh 20 | *.bak 21 | *.[Cc]ache 22 | *.ilk 23 | *.log 24 | *.lib 25 | *.sbr 26 | *.sdf 27 | *.opensdf 28 | *.resources 29 | *.res 30 | ipch/ 31 | obj/ 32 | [Bb]in 33 | [Dd]ebug*/ 34 | [Rr]elease*/ 35 | Ankh.NoLoad 36 | *.gpState 37 | 38 | # MonoDevelop 39 | *.userprefs 40 | 41 | # Tooling 42 | _ReSharper*/ 43 | *.resharper 44 | [Tt]est[Rr]esult* 45 | *.nvuser 46 | 47 | # Project files 48 | #[Bb]uild/ 49 | 50 | # Subversion files 51 | .svn 52 | 53 | # NuGet packages 54 | !.nuget/* 55 | [Pp]ackages/* 56 | ![Pp]ackages/repositories.config 57 | 58 | # Office Temp Files 59 | ~$* 60 | -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jack-pappas/fsharp-logic-examples/1e12807ed98301b94bb6b3aa61e1b06089eec269/.nuget/NuGet.exe -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | 3 | # Use container-based infrastructure with Ubuntu Trusty (14.04) 4 | dist: trusty 5 | sudo: false 6 | 7 | # TODO : Enable both mono and dotnet builds: https://docs.travis-ci.com/user/languages/csharp/#Testing-Against-Mono-and-.NET-Core 8 | mono: 9 | - latest 10 | 11 | env: 12 | global: 13 | - EnableNuGetPackageRestore=true 14 | 15 | install: 16 | - nuget restore FSharpx.Books.AutomatedReasoning.VS11.sln 17 | - nuget install NUnit.Runners -Version 2.6.4 -OutputDirectory tools 18 | 19 | script: 20 | - xbuild /property:Configuration=Release FSharpx.Books.AutomatedReasoning.VS11.sln 21 | - mono --runtime=v4.0.30319 ./tools/NUnit.Runners.2.6.4/tools/nunit-console.exe ./FSharpx.Books.AutomatedReasoning.Tests/bin/Release/FSharpx.Books.AutomatedReasoning.Tests.dll -exclude:LongRunning 22 | -------------------------------------------------------------------------------- /Examples/bdd.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | open FSharpx.Books.AutomatedReasoning.bdd 14 | 15 | // pg. 105 16 | // ------------------------------------------------------------------------- // 17 | // Examples. // 18 | // ------------------------------------------------------------------------- // 19 | 20 | // bdd.p001 21 | bddtaut (mk_adder_test 4 2);; 22 | 23 | // pg. 107 24 | // ------------------------------------------------------------------------- // 25 | // Examples. // 26 | // ------------------------------------------------------------------------- // 27 | 28 | // bdd.p002 29 | ebddtaut (prime 101);; 30 | 31 | // bdd.p003 32 | ebddtaut (mk_adder_test 9 5);; 33 | -------------------------------------------------------------------------------- /Examples/cong.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.stal 13 | open FSharpx.Books.AutomatedReasoning.fol 14 | open FSharpx.Books.AutomatedReasoning.skolem 15 | open FSharpx.Books.AutomatedReasoning.meson 16 | open FSharpx.Books.AutomatedReasoning.equal 17 | open FSharpx.Books.AutomatedReasoning.cong 18 | 19 | fsi.AddPrinter sprint_fol_formula 20 | 21 | // pg. 253 22 | // ------------------------------------------------------------------------- // 23 | // Example. // 24 | // ------------------------------------------------------------------------- // 25 | 26 | // cong.p001 27 | ccvalid (parse 28 | @"f(f(f(f(f(c))))) = c /\ f(f(f(c))) = c 29 | ==> f(c) = c \/ f(g(c)) = g(f(c))");; 30 | 31 | // cong.p002 32 | ccvalid (parse 33 | @"f(f(f(f(c)))) = c /\ f(f(c)) = c ==> f(c) = c");; 34 | 35 | // ------------------------------------------------------------------------- // 36 | // For debugging. Maybe I will incorporate into a prettyprinter one day. // 37 | // ------------------------------------------------------------------------- // 38 | 39 | let showequiv ptn = 40 | let fn = reverseq (equated ptn) ptn 41 | List.map (apply fn) (dom fn);; 42 | 43 | // cong.p003 44 | // Added by EGT 45 | ccvalid (parse 46 | @"f(a,b) = a ==> f(f(a,b), b) = a");; -------------------------------------------------------------------------------- /Examples/defcnf.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.defcnf 14 | 15 | fsi.AddPrinter sprint_prop_formula 16 | 17 | // pg. 74 18 | // ------------------------------------------------------------------------- // 19 | // Example. // 20 | // ------------------------------------------------------------------------- // 21 | 22 | // defcnf.p001 23 | cnf (parse_prop_formula @"p <=> (q <=> r)");; 24 | 25 | // pg. 77 26 | // ------------------------------------------------------------------------- // 27 | // Example. // 28 | // ------------------------------------------------------------------------- // 29 | 30 | // defcnf.p002 31 | defcnfOrig (parse_prop_formula @"(p \/ (q /\ ~r)) /\ s");; 32 | 33 | // pg. 78 34 | // ------------------------------------------------------------------------- // 35 | // Examples. // 36 | // ------------------------------------------------------------------------- // 37 | 38 | // defcnf.p003 39 | defcnf (parse_prop_formula @"(p \/ (q /\ ~r)) /\ s");; 40 | -------------------------------------------------------------------------------- /Examples/dp.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | open FSharpx.Books.AutomatedReasoning.defcnf 14 | open FSharpx.Books.AutomatedReasoning.dp 15 | 16 | // pg. 84 17 | // ------------------------------------------------------------------------- // 18 | // Examples. // 19 | // ------------------------------------------------------------------------- // 20 | 21 | // dp.p001 22 | tautology(prime 11);; 23 | 24 | // dp.p002 25 | dptaut(prime 11);; 26 | 27 | // pg. 85 28 | // ------------------------------------------------------------------------- // 29 | // Example. // 30 | // ------------------------------------------------------------------------- // 31 | 32 | // dp.p003 33 | dplltaut(prime 11);; 34 | 35 | // pg. 89 36 | // ------------------------------------------------------------------------- // 37 | // Examples. // 38 | // ------------------------------------------------------------------------- // 39 | 40 | // dp.p004 41 | // Real: 00:05:30.392, CPU: 00:05:30.031, GC gen0: 1458, gen1: 137, gen2: 4 42 | dplitaut(prime 101);; 43 | 44 | // dp.p005 45 | // Real: 00:01:37.614, CPU: 00:01:37.453, GC gen0: 426, gen1: 14, gen2: 1 46 | dplbtaut(prime 101);; 47 | -------------------------------------------------------------------------------- /Examples/fol.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.fol 14 | 15 | // pg. 119 16 | // ------------------------------------------------------------------------- // 17 | // Example. // 18 | // ------------------------------------------------------------------------- // 19 | 20 | // fol.p001 21 | Fn("sqrt",[Fn("-",[Fn("1",[]); 22 | Fn("power",[Fn("cos",[Fn("+",[Var "x"; Var "y"])]); 23 | Fn("2",[])])])]);; // From errata 24 | 25 | // pg. 119 26 | // ------------------------------------------------------------------------- // 27 | // Trivial example of "x + y < z". // 28 | // ------------------------------------------------------------------------- // 29 | 30 | // fol.p002 31 | Atom(R("<",[Fn("+",[Var "x"; Var "y"]); Var "z"]));; 32 | 33 | // Not in book 34 | // ------------------------------------------------------------------------- // 35 | // Example. // 36 | // ------------------------------------------------------------------------- // 37 | 38 | // fol.p003 39 | // TODO: Why does this fail to parse? 40 | //parse @"forall x. x < 2 ==> 2 * x <= 3) \/ false";; 41 | 42 | // fol.p004 43 | parset ("2 * x");; 44 | 45 | fsi.AddPrinter sprint_term 46 | fsi.AddPrinter sprint_fol_formula 47 | 48 | // pg. 123 49 | // ------------------------------------------------------------------------- // 50 | // Example. // 51 | // ------------------------------------------------------------------------- // 52 | 53 | // fol.p005 54 | (parse @"forall x y. exists z. x < z /\ y < z");; 55 | 56 | // fol.p006 57 | (parse @"~(forall x. P(x)) <=> exists y. ~P(y)");; 58 | 59 | // pg. 126 60 | // fol.p007 61 | // Harrison #06 62 | holds bool_interp undefined (parse @"forall x. (x = 0) \/ (x = 1)");; 63 | 64 | // fol.p008 65 | // Harrison #06 66 | holds (mod_interp 2) undefined (parse @"forall x. (x = 0) \/ (x = 1)");; 67 | 68 | // fol.p009 69 | // Harrison #06 70 | holds (mod_interp 3) undefined (parse @"forall x. (x = 0) \/ (x = 1)");; 71 | 72 | let fm = (parse @"forall x. ~(x = 0) ==> exists y. x * y = 1");; 73 | 74 | // fol.p010 75 | List.filter (fun n -> holds (mod_interp n) undefined fm) (1--45);; 76 | 77 | // pg. 129 78 | // fol.p011 79 | holds (mod_interp 3) undefined (parse @"(forall x. x = 0) ==> 1 = 0");; 80 | 81 | // fol.p012 82 | holds (mod_interp 3) undefined (parse @"forall x. x = 0 ==> 1 = 0");; 83 | 84 | // pg. 133 85 | // ------------------------------------------------------------------------- // 86 | // Variant function and examples. // 87 | // ------------------------------------------------------------------------- // 88 | 89 | // fol.p013 90 | variant "x" ["y"; "z"];; 91 | 92 | // fol.p014 93 | variant "x" ["x"; "y"];; 94 | 95 | // fol.p015 96 | variant "x" ["x"; "x'"];; 97 | 98 | // pg. 134 99 | // ------------------------------------------------------------------------- // 100 | // Examples. // 101 | // ------------------------------------------------------------------------- // 102 | 103 | // fol.p016 104 | (subst ("y" |=> Var "x") (parse @"forall x. x = y"));; 105 | 106 | // fol.p017 107 | (subst ("y" |=> Var "x") (parse @"forall x x'. x = y ==> x = x'"));; 108 | -------------------------------------------------------------------------------- /Examples/folderived.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.fol 10 | open FSharpx.Books.AutomatedReasoning.lcf 11 | open FSharpx.Books.AutomatedReasoning.folderived 12 | 13 | fsi.AddPrinter sprint_thm 14 | 15 | // pg. 490 16 | // ------------------------------------------------------------------------- // 17 | // Example. // 18 | // ------------------------------------------------------------------------- // 19 | 20 | // folderived.p001 21 | icongruence (parset @"s") (parset @"t") (parset @"f(s,g(s,t,s),u,h(h(s)))") 22 | (parset @"f(s,g(t,t,s),u,h(h(t)))");; 23 | 24 | // pg. 494 25 | // ------------------------------------------------------------------------- // 26 | // An example. // 27 | // ------------------------------------------------------------------------- // 28 | 29 | // folderived.p002 30 | ispec (parset @"y") (parse @"forall x y z. x + y + z = z + y + x");; 31 | 32 | // ------------------------------------------------------------------------- // 33 | // Additional tests not in main text. // 34 | // ------------------------------------------------------------------------- // 35 | 36 | // folderived.p003 37 | isubst (parset @"x + x") (parset @"2 * x") 38 | (parse @"x + x = x ==> x = 0") (parse @"2 * x = x ==> x = 0");; 39 | 40 | // folderived.p004 41 | isubst (parset @"x + x") (parset @"2 * x") 42 | (parse @"(x + x = y + y) ==> (y + y + y = x + x + x)") 43 | (parse @"2 * x = y + y ==> y + y + y = x + 2 * x");; 44 | 45 | // folderived.p005 46 | ispec (parset @"x") (parse @"forall x y z. x + y + z = y + z + z");; 47 | 48 | // folderived.p006 49 | ispec (parset @"x") (parse @"forall x. x = x");; 50 | 51 | // folderived.p007 52 | ispec (parset @"w + y + z") (parse @"forall x y z. x + y + z = y + z + z");; 53 | 54 | // folderived.p008 55 | ispec (parset @"x + y + z") (parse @"forall x y z. x + y + z = y + z + z");; 56 | 57 | // folderived.p009 58 | ispec (parset @"x + y + z") (parse @"forall x y z. nothing_much");; 59 | 60 | // folderived.p010 61 | isubst (parset @"x + x") (parset @"2 * x") 62 | (parse @"(x + x = y + y) <=> (something \/ y + y + y = x + x + x)") 63 | (parse @"(2 * x = y + y) <=> (something \/ y + y + y = x + x + x)");; 64 | 65 | // folderived.p011 66 | isubst (parset @"x + x") (parset @"2 * x") 67 | (parse @"(exists x. x = 2) <=> exists y. y + x + x = y + y + y") 68 | (parse @"(exists x. x = 2) <=> (exists y. y + 2 * x = y + y + y)");; 69 | 70 | // folderived.p012 71 | isubst (parset @"x") (parset @"y") 72 | (parse @"(forall z. x = z) <=> (exists x. y < z) /\ (forall y. y < x)") 73 | (parse @"(forall z. y = z) <=> (exists x. y < z) /\ (forall y'. y' < y)");; 74 | 75 | // ------------------------------------------------------------------------- // 76 | // The bug is now fixed. // 77 | // ------------------------------------------------------------------------- // 78 | 79 | // folderived.p013 80 | ispec (parset @"x'") (parse @"forall x x' x''. x + x' + x'' = 0");; 81 | 82 | // folderived.p014 83 | ispec (parset @"x''") (parse @"forall x x' x''. x + x' + x'' = 0");; 84 | 85 | // folderived.p015 86 | ispec (parset @"x' + x''") (parse @"forall x x' x''. x + x' + x'' = 0");; 87 | 88 | // folderived.p016 89 | ispec (parset @"x + x' + x''") (parse @"forall x x' x''. x + x' + x'' = 0");; 90 | 91 | // folderived.p017 92 | ispec (parset @"2 * x") (parse @"forall x x'. x + x' = x' + x");; -------------------------------------------------------------------------------- /Examples/herbrand.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.initialization 10 | open FSharpx.Books.AutomatedReasoning.lib 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.dp 14 | open FSharpx.Books.AutomatedReasoning.fol 15 | open FSharpx.Books.AutomatedReasoning.skolem 16 | open FSharpx.Books.AutomatedReasoning.herbrand 17 | 18 | fsi.AddPrinter sprint_fol_formula 19 | 20 | // pg. 161 21 | // ------------------------------------------------------------------------- // 22 | // First example and a little tracing. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | // herbrand.p001 26 | // Harrison #07 27 | gilmore (parse @"exists x. forall y. P(x) ==> P(y)");; 28 | 29 | // herbrand.p002 30 | // Harrison #07 31 | let sfm = skolemize(Not (parse @"exists x. forall y. P(x) ==> P(y)"));; 32 | 33 | // pg. 161 34 | // ------------------------------------------------------------------------- // 35 | // Quick example. // 36 | // ------------------------------------------------------------------------- // 37 | 38 | // herbrand.p003 39 | // Pelletier #24 40 | let p24 = gilmore (parse @" 41 | ~(exists x. U(x) /\ Q(x)) 42 | /\ (forall x. P(x) ==> Q(x) \/ R(x)) 43 | /\ ~(exists x. P(x) ==> (exists x. Q(x))) 44 | /\ (forall x. Q(x) 45 | /\ R(x) ==> U(x)) ==> (exists x. P(x) /\ R(x))");; 46 | 47 | // pg. 162 48 | // ------------------------------------------------------------------------- // 49 | // Slightly less easy example. // 50 | // ------------------------------------------------------------------------- // 51 | 52 | // herbrand.p004 53 | // Pelletier #45 54 | // Real: 00:00:27.907, CPU: 00:00:27.906, GC gen0: 7, gen1: 6, gen2: 1 55 | let p45 = runWithEnlargedStack (fun () -> 56 | gilmore (parse @" 57 | (forall x. P(x) 58 | /\ (forall y. G(y) /\ H(x,y) ==> J(x,y)) ==> (forall y. G(y) /\ H(x,y) ==> R(y))) 59 | /\ ~(exists y. L(y) /\ R(y)) 60 | /\ (exists x. P(x) /\ (forall y. H(x,y) ==> L(y)) 61 | /\ (forall y. G(y) /\ H(x,y) ==> J(x,y))) ==> (exists x. P(x) /\ ~(exists y. G(y) /\ H(x,y)))"));; 62 | 63 | // pg. 162 64 | // ------------------------------------------------------------------------- // 65 | // Apparently intractable example. // 66 | // ------------------------------------------------------------------------- // 67 | 68 | // herbrand.p005 69 | // Pelletier #20 70 | //let p20 = gilmore (parse @"(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w)) 71 | // ==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))");; 72 | 73 | // pg. 163 74 | // ------------------------------------------------------------------------- // 75 | // Show how much better than the Gilmore procedure this can be. // 76 | // ------------------------------------------------------------------------- // 77 | 78 | // herbrand.p006 79 | // Pelletier #20 80 | let p20dp = davisputnam (parse @" 81 | (forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w)) 82 | ==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))");; 83 | 84 | // herbrand.p007 85 | // Pelletier #36 86 | let p36 = davisputnam002 (parse @" 87 | (forall x. exists y. P(x,y)) 88 | /\ (forall x. exists y. G(x,y)) 89 | /\ (forall x y. P(x,y) \/ G(x,y) ==> (forall z. P(y,z) \/ G(y,z) ==> H(x,z))) 90 | ==> (forall x. exists y. H(x,y))");; 91 | 92 | // herbrand.p008 93 | // Real: 00:01:50.847, CPU: 00:01:50.687, GC gen0: 382, gen1: 111, gen2: 1 94 | // Pelletier #29 95 | let p29 = davisputnam002 (parse @" 96 | (exists x. P(x)) /\ (exists x. G(x)) ==> 97 | ((forall x. P(x) ==> H(x)) /\ (forall x. G(x) ==> J(x)) <=> 98 | (forall x y. P(x) /\ G(y) ==> H(x) /\ J(y)))");; 99 | -------------------------------------------------------------------------------- /Examples/init_all.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharp.Compatibility.OCaml 10 | 11 | open FSharpx.Books.AutomatedReasoning.lib 12 | open FSharpx.Books.AutomatedReasoning.intro 13 | open FSharpx.Books.AutomatedReasoning.formulas 14 | open FSharpx.Books.AutomatedReasoning.prop 15 | open FSharpx.Books.AutomatedReasoning.propexamples 16 | open FSharpx.Books.AutomatedReasoning.defcnf 17 | open FSharpx.Books.AutomatedReasoning.dp 18 | open FSharpx.Books.AutomatedReasoning.stal 19 | open FSharpx.Books.AutomatedReasoning.bdd 20 | open FSharpx.Books.AutomatedReasoning.fol 21 | open FSharpx.Books.AutomatedReasoning.skolem 22 | open FSharpx.Books.AutomatedReasoning.herbrand 23 | open FSharpx.Books.AutomatedReasoning.unif 24 | open FSharpx.Books.AutomatedReasoning.tableaux 25 | open FSharpx.Books.AutomatedReasoning.resolution 26 | open FSharpx.Books.AutomatedReasoning.prolog 27 | open FSharpx.Books.AutomatedReasoning.meson 28 | open FSharpx.Books.AutomatedReasoning.skolems 29 | open FSharpx.Books.AutomatedReasoning.equal 30 | open FSharpx.Books.AutomatedReasoning.cong 31 | open FSharpx.Books.AutomatedReasoning.rewrite 32 | open FSharpx.Books.AutomatedReasoning.order 33 | open FSharpx.Books.AutomatedReasoning.completion 34 | open FSharpx.Books.AutomatedReasoning.eqelim 35 | open FSharpx.Books.AutomatedReasoning.paramodulation 36 | open FSharpx.Books.AutomatedReasoning.decidable 37 | open FSharpx.Books.AutomatedReasoning.qelim 38 | open FSharpx.Books.AutomatedReasoning.cooper 39 | open FSharpx.Books.AutomatedReasoning.complex 40 | open FSharpx.Books.AutomatedReasoning.real 41 | open FSharpx.Books.AutomatedReasoning.grobner 42 | open FSharpx.Books.AutomatedReasoning.geom 43 | open FSharpx.Books.AutomatedReasoning.interpolation 44 | open FSharpx.Books.AutomatedReasoning.combining 45 | open FSharpx.Books.AutomatedReasoning.lcf 46 | open FSharpx.Books.AutomatedReasoning.lcfprop 47 | open FSharpx.Books.AutomatedReasoning.folderived 48 | open FSharpx.Books.AutomatedReasoning.lcffol 49 | open FSharpx.Books.AutomatedReasoning.tactics 50 | open FSharpx.Books.AutomatedReasoning.limitations -------------------------------------------------------------------------------- /Examples/initialization.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2012 Jack Pappas, Anh-Dung Phan // 3 | // (See "LICENSE.txt" for details.) // 4 | // ========================================================================= // 5 | 6 | // ========================================================================= // 7 | // Tweak F# default state for theorem proving code. // 8 | // ========================================================================= // 9 | 10 | #I @".\..\FSharpx.Books.AutomatedReasoning\bin\Debug" 11 | #r @"FSharpx.Books.AutomatedReasoning.dll" 12 | #r @"FSharp.Compatibility.OCaml.dll" 13 | 14 | // Reduce margins 15 | fsi.PrintWidth <- 72;; 16 | 17 | // Open bignums 18 | open FSharp.Compatibility.OCaml;; 19 | #nowarn "62";; 20 | open FSharp.Compatibility.OCaml.Num;; 21 | 22 | // Print the full value of a Num instead of truncating it. 23 | fsi.AddPrinter (fun (n : Num) -> n.ToString ());; 24 | -------------------------------------------------------------------------------- /Examples/interpolation.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.formulas 10 | open FSharpx.Books.AutomatedReasoning.prop 11 | open FSharpx.Books.AutomatedReasoning.fol 12 | open FSharpx.Books.AutomatedReasoning.skolem 13 | open FSharpx.Books.AutomatedReasoning.herbrand 14 | open FSharpx.Books.AutomatedReasoning.meson 15 | open FSharpx.Books.AutomatedReasoning.interpolation 16 | 17 | fsi.AddPrinter sprint_fol_formula 18 | 19 | // pg. 429 20 | // ------------------------------------------------------------------------- // 21 | // Example. // 22 | // ------------------------------------------------------------------------- // 23 | 24 | // interpolation.p001 25 | let p002 = prenex (parse @"(forall x. R(x,f(x))) /\ (forall x y. S(x,y) <=> R(x,y) \/ R(y,x))");; 26 | 27 | // interpolation.p002 28 | let q002 = prenex (parse @"(forall x y z. S(x,y) /\ S(y,z) ==> T(x,z)) /\ ~T(0,0)");; 29 | 30 | // interpolation.p003 31 | let c002 = urinterpolate p002 q002;; 32 | 33 | // interpolation.p004 34 | meson002(Imp(p002,c002));; 35 | 36 | // interpolation.p005 37 | meson002(Imp(q002,Not c002));; 38 | 39 | // pg. 433 40 | // ------------------------------------------------------------------------- // 41 | // The same example now gives a true interpolant. // 42 | // ------------------------------------------------------------------------- // 43 | 44 | // interpolation.p006 45 | let c003 = uinterpolate p002 q002;; 46 | 47 | // interpolation.p007 48 | meson002(Imp(p002,c003));; 49 | 50 | // interpolation.p008 51 | meson002(Imp(q002,Not c003));; 52 | 53 | // pg. 434 54 | // ------------------------------------------------------------------------- // 55 | // Example. // 56 | // ------------------------------------------------------------------------- // 57 | 58 | let p004 = (parse @"(forall x. exists y. R(x,y)) /\ (forall x y. S(v,x,y) <=> R(x,y) \/ R(y,x))");; 59 | 60 | let q004 = (parse @"(forall x y z. S(v,x,y) /\ S(v,y,z) ==> T(x,z)) /\ (exists u. ~T(u,u))");; 61 | 62 | // interpolation.p009 63 | let c004 = interpolate p004 q004;; 64 | 65 | // interpolation.p010 66 | meson002(Imp(p004,c004));; 67 | 68 | // interpolation.p011 69 | meson002(Imp(q004,Not c004));; 70 | 71 | // ------------------------------------------------------------------------- // 72 | // More examples, not in the text. // 73 | // ------------------------------------------------------------------------- // 74 | 75 | let p005 = (parse @"(p ==> q /\ r)");; 76 | 77 | let q005 = (parse @"~((q ==> p) ==> s ==> (p <=> q))");; 78 | 79 | // interpolation.p012 80 | let c005 = interpolate p005 q005;; 81 | 82 | // interpolation.p013 83 | tautology(Imp(And(p005,q005),False));; 84 | 85 | // interpolation.p014 86 | tautology(Imp(p005,c005));; 87 | 88 | // interpolation.p015 89 | tautology(Imp(q005,Not c005));; 90 | 91 | // ------------------------------------------------------------------------- // 92 | // A more interesting example. // 93 | // ------------------------------------------------------------------------- // 94 | 95 | let p006 = (parse @"(forall x. exists y. R(x,y)) /\ (forall x y. S(x,y) <=> R(x,y) \/ R(y,x))");; 96 | 97 | let q006 = (parse @"(forall x y z. S(x,y) /\ S(y,z) ==> T(x,z)) /\ ~T(u,u)");; 98 | 99 | // interpolation.p016 100 | meson002(Imp(And(p006,q006),False));; 101 | 102 | // interpolation.p017 103 | let c006 = interpolate p006 q006;; 104 | 105 | // interpolation.p018 106 | meson002(Imp(p006,c006));; 107 | 108 | // interpolation.p019 109 | meson002(Imp(q006,Not c006));; 110 | 111 | // ------------------------------------------------------------------------- // 112 | // A variant where u is free in both parts. // 113 | // ------------------------------------------------------------------------- // 114 | 115 | let p007 = (parse @"(forall x. exists y. R(x,y)) /\ (forall x y. S(x,y) <=> R(x,y) \/ R(y,x)) /\ (forall v. R(u,v) ==> Q(v,u))");; 116 | 117 | let q007 = (parse @"(forall x y z. S(x,y) /\ S(y,z) ==> T(x,z)) /\ ~T(u,u)");; 118 | 119 | // interpolation.p020 120 | meson002(Imp(And(p007,q007),False));; 121 | 122 | // interpolation.p021 123 | let c007 = interpolate p007 q007;; 124 | 125 | // interpolation.p022 126 | meson002(Imp(p007,c007));; 127 | 128 | // interpolation.p023 129 | meson002(Imp(q007,Not c007));; 130 | 131 | // ------------------------------------------------------------------------- // 132 | // Way of generating examples quite easily (see K&K exercises). // 133 | // ------------------------------------------------------------------------- // 134 | 135 | let test_interp fm = 136 | let rec p = generalize (skolemize fm) 137 | and q = generalize (skolemize (Not fm)) 138 | let c = interpolate p q 139 | meson002(Imp(And(p,q),False)) |> ignore 140 | meson002(Imp(p,c)) |> ignore 141 | meson002(Imp(q,Not c)) |> ignore 142 | c;; 143 | 144 | // interpolation.p024 145 | test_interp (parse @"forall x. P(x) ==> exists y. forall z. P(z) ==> Q(y)");; 146 | 147 | // interpolation.p025 148 | test_interp (parse @"forall y. exists y. forall z. exists a. P(a,x,y,z) ==> P(x,y,z,a)");; 149 | 150 | // ------------------------------------------------------------------------- // 151 | // Hintikka's examples. // 152 | // ------------------------------------------------------------------------- // 153 | 154 | let p009 = (parse @"forall x. L(x,b)");; 155 | 156 | let q009 = (parse @"(forall y. L(b,y) ==> m = y) /\ ~(m = b)");; 157 | 158 | // interpolation.p026 159 | let c009 = einterpolate p009 q009;; 160 | 161 | // interpolation.p027 162 | meson002(Imp(p009,c009));; 163 | 164 | // interpolation.p028 165 | meson002(Imp(q009,Not c009));; 166 | 167 | let p010 = (parse @"(forall x. A(x) /\ C(x) ==> B(x)) /\ (forall x. D(x) \/ ~D(x) ==> C(x))");; 168 | 169 | let q010 = (parse @"~(forall x. E(x) ==> A(x) ==> B(x))");; 170 | 171 | // interpolation.p029 172 | let c010 = interpolate p010 q010;; 173 | 174 | // interpolation.p030 175 | meson002(Imp(p010,c010));; 176 | 177 | // interpolation.p031 178 | meson002(Imp(q010,Not c010));; 179 | -------------------------------------------------------------------------------- /Examples/intro.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | 12 | // pg. 14 13 | // ------------------------------------------------------------------------- // 14 | // Trivial example of using the type constructors. // 15 | // ------------------------------------------------------------------------- // 16 | 17 | // intro.p001 18 | Add (Mul (Const 2, Var "x"), Var "y");; 19 | 20 | // pg. 16 21 | // ------------------------------------------------------------------------- // 22 | // Example. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | let e = Add (Mul (Add (Mul (Const 0, Var "x"), Const 1), Const 3), Const 12);; 26 | 27 | // intro.p002 28 | simplify e;; 29 | 30 | // intro.p003 31 | lex (explode @"2*((var_1 + x') + 11)");; 32 | 33 | // intro.p004 34 | lex (explode @"if //p1-- == *p2++) then f() else g()");; 35 | 36 | // pg. 20 37 | // ------------------------------------------------------------------------- // 38 | // Our parser. // 39 | // ------------------------------------------------------------------------- // 40 | 41 | // intro.p005 42 | parse_exp @"x + 1";; 43 | 44 | fsi.AddPrinter sprint_exp;; 45 | 46 | // pg. 21 47 | // ------------------------------------------------------------------------- // 48 | // Demonstrate automatic installation. // 49 | // ------------------------------------------------------------------------- // 50 | 51 | // intro.p006 52 | parse_exp @"(x1 + x2 + x3) * (1 + 2 + 3 * x + y)";; 53 | 54 | // pg. 21 55 | // ------------------------------------------------------------------------- // 56 | // Examples. // 57 | // ------------------------------------------------------------------------- // 58 | 59 | // intro.p007 60 | string_of_exp (parse_exp @"x + 3 * y");; 61 | 62 | // intro.p008 63 | parse_exp @"x + 3 * y";; 64 | 65 | // intro.p009 66 | parse_exp @"(x + 3) * y";; 67 | 68 | // intro.p010 69 | parse_exp @"1 + 2 + 3";; 70 | 71 | // intro.p011 72 | parse_exp @"((1 + 2) + 3) + 4";; 73 | 74 | // pg. 22 75 | // ------------------------------------------------------------------------- // 76 | // Example shows the problem. // 77 | // ------------------------------------------------------------------------- // 78 | 79 | // intro.p012 80 | parse_exp @"(x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) * (y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8 + y9 + y10)";; -------------------------------------------------------------------------------- /Examples/lcfprop.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.fol 10 | open FSharpx.Books.AutomatedReasoning.lcf 11 | open FSharpx.Books.AutomatedReasoning.lcfprop 12 | 13 | fsi.AddPrinter sprint_thm 14 | 15 | // pg. 488 16 | // ------------------------------------------------------------------------- // 17 | // The examples in the text. // 18 | // ------------------------------------------------------------------------- // 19 | 20 | // lcfprop.p001 21 | // Pelletier #16 22 | lcftaut (parse @"(p ==> q) \/ (q ==> p)") ;; 23 | 24 | // lcfprop.p002 25 | // Harrison #02 - Equations within equations 26 | lcftaut (parse @"p /\ q <=> ((p <=> q) <=> p \/ q)");; 27 | 28 | // lcfprop.p003 29 | // Pelletier #12 30 | lcftaut (parse @"((p <=> q) <=> r) <=> (p <=> (q <=> r))");; 31 | -------------------------------------------------------------------------------- /Examples/order.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.order 12 | 13 | fsi.AddPrinter sprint_term 14 | 15 | // ------------------------------------------------------------------------- // 16 | // This fails the rewrite properties. // 17 | // ------------------------------------------------------------------------- // 18 | 19 | let s = parset @"f(x,x,x)";; 20 | 21 | let t = parset @"g(x,y)";; 22 | 23 | // order.p001 24 | termsize s > termsize t;; 25 | 26 | let i = "y" |=> parset @"f(x,x,x)";; 27 | 28 | // order.p002 29 | termsize (tsubst i s) > termsize (tsubst i t);; 30 | -------------------------------------------------------------------------------- /Examples/paramodulation.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.fol 13 | open FSharpx.Books.AutomatedReasoning.skolem 14 | open FSharpx.Books.AutomatedReasoning.resolution 15 | open FSharpx.Books.AutomatedReasoning.equal 16 | open FSharpx.Books.AutomatedReasoning.completion 17 | open FSharpx.Books.AutomatedReasoning.paramodulation 18 | 19 | // pg. 302 20 | // ------------------------------------------------------------------------- // 21 | // Test. // 22 | // ------------------------------------------------------------------------- // 23 | 24 | // paramodulation.p001 25 | paramodulation 26 | (parse @" 27 | (forall x. f(f(x)) = f(x)) /\ (forall x. exists y. f(y) = x) 28 | ==> forall x. f(x) = x");; 29 | -------------------------------------------------------------------------------- /Examples/prolog.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.fol 14 | open FSharpx.Books.AutomatedReasoning.skolem 15 | open FSharpx.Books.AutomatedReasoning.unif 16 | open FSharpx.Books.AutomatedReasoning.tableaux 17 | open FSharpx.Books.AutomatedReasoning.resolution 18 | open FSharpx.Books.AutomatedReasoning.prolog 19 | 20 | fsi.AddPrinter sprint_term 21 | fsi.AddPrinter sprint_fol_formula 22 | 23 | // pg. 208 24 | // ------------------------------------------------------------------------- // 25 | // A Horn example. // 26 | // ------------------------------------------------------------------------- // 27 | 28 | // prolog.p001 29 | // Pelletier #32 30 | let p32 = 31 | hornprove (parse @" 32 | (forall x. P(x) /\ (G(x) \/ H(x)) ==> Q(x)) /\ 33 | (forall x. Q(x) /\ H(x) ==> J(x)) /\ 34 | (forall x. R(x) ==> H(x)) 35 | ==> (forall x. P(x) /\ R(x) ==> J(x))");; 36 | 37 | // pg. 208 38 | // ------------------------------------------------------------------------- // 39 | // A non-Horn example. // 40 | // ------------------------------------------------------------------------- // 41 | 42 | // prolog.p002 43 | // System.Exception: non-Horn clause. - This is the expected result. 44 | // Pelletier #09 45 | hornprove (parse @"(p \/ q) /\ (~p \/ q) /\ (p \/ ~q) ==> ~(~q \/ ~q)");; 46 | 47 | // pg. 210 48 | // ------------------------------------------------------------------------- // 49 | // Ordering example. // 50 | // ------------------------------------------------------------------------- // 51 | 52 | let lerules = ["0 <= X"; "S(X) <= S(Y) :- X <= Y"];; 53 | 54 | // prolog.p003 55 | simpleprolog lerules @"S(S(0)) <= S(S(S(0)))";; 56 | 57 | // prolog.p004 58 | // System.Exception: tryfind - This is the expected result. 59 | simpleprolog lerules @"S(S(0)) <= S(0)";; 60 | 61 | let env = simpleprolog lerules @"S(S(0)) <= X";; 62 | // prolog.p005 63 | apply env "X";; 64 | 65 | // pg. 211 66 | // ------------------------------------------------------------------------- // 67 | // Example again. // 68 | // ------------------------------------------------------------------------- // 69 | 70 | // prolog.p006 71 | prolog lerules @"S(S(0)) <= X";; 72 | 73 | // pg. 211 74 | // ------------------------------------------------------------------------- // 75 | // Append example, showing symmetry between inputs and outputs. // 76 | // ------------------------------------------------------------------------- // 77 | 78 | let appendrules = [ 79 | @"append(nil,L,L)"; 80 | @"append(H::T,L,H::A) :- append(T,L,A)";];; 81 | 82 | // prolog.p007 83 | prolog appendrules @"append(1::2::nil,3::4::nil,Z)";; 84 | 85 | // prolog.p008 86 | prolog appendrules @"append(1::2::nil,Y,1::2::3::4::nil)";; 87 | 88 | // prolog.p009 89 | prolog appendrules @"append(X,3::4::nil,1::2::3::4::nil)";; 90 | 91 | // prolog.p010 92 | prolog appendrules @"append(X,Y,1::2::3::4::nil)";; 93 | 94 | // pg. 211 95 | // ------------------------------------------------------------------------- // 96 | // However this way round doesn't work. // 97 | // ------------------------------------------------------------------------- // 98 | 99 | // prolog.p011 100 | // Process is terminated due to StackOverflowException. - This is the expected result. 101 | prolog appendrules "append(X,3::4::nil,X)";; 102 | 103 | // pg. 212 104 | // ------------------------------------------------------------------------- // 105 | // A sorting example (from Lloyd's "Foundations of Logic Programming"). // 106 | // ------------------------------------------------------------------------- // 107 | 108 | let sortrules = [ 109 | @"sort(X,Y) :- perm(X,Y),sorted(Y)"; 110 | @"sorted(nil)"; 111 | @"sorted(X::nil)"; 112 | @"sorted(X::Y::Z) :- X <= Y, sorted(Y::Z)"; 113 | @"perm(nil,nil)"; 114 | @"perm(X::Y,U::V) :- delete(U,X::Y,Z), perm(Z,V)"; 115 | @"delete(X,X::Y,Y)"; 116 | @"delete(X,Y::Z,Y::W) :- delete(X,Z,W)"; 117 | @"0 <= X"; 118 | @"S(X) <= S(Y) :- X <= Y"; ];; 119 | 120 | // prolog.p012 121 | prolog sortrules 122 | @"sort(S(S(S(S(0))))::S(0)::0::S(S(0))::S(0)::nil,X)";; 123 | 124 | // Not it book 125 | // ------------------------------------------------------------------------- // 126 | // Yet with a simple swap of the first two predicates... // 127 | // ------------------------------------------------------------------------- // 128 | 129 | let badrules = [ 130 | @"sort(X,Y) :- sorted(Y), perm(X,Y)"; 131 | @"sorted(nil)"; 132 | @"sorted(X::nil)"; 133 | @"sorted(X::Y::Z) :- X <= Y, sorted(Y::Z)"; 134 | @"perm(nil,nil)"; 135 | @"perm(X::Y,U::V) :- delete(U,X::Y,Z), perm(Z,V)"; 136 | @"delete(X,X::Y,Y)"; 137 | @"delete(X,Y::Z,Y::W) :- delete(X,Z,W)"; 138 | @"0 <= X"; 139 | @"S(X) <= S(Y) :- X <= Y"; ];; 140 | 141 | //** This no longer works 142 | 143 | // prolog.p013 144 | // Process is terminated due to StackOverflowException. - This is the expected result. 145 | prolog badrules 146 | @"sort(S(S(S(S(0))))::S(0)::0::S(S(0))::S(0)::nil,X)";; 147 | -------------------------------------------------------------------------------- /Examples/propexamples.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | 14 | fsi.AddPrinter sprint_prop_formula 15 | 16 | // pg. 63 17 | // ------------------------------------------------------------------------- // 18 | // Some currently tractable examples. // 19 | // ------------------------------------------------------------------------- // 20 | 21 | // propexamples.p001 22 | ramsey 3 3 4;; 23 | 24 | // propexamples.p002 25 | tautology(ramsey 3 3 5);; 26 | 27 | // propexamples.p003 28 | tautology(ramsey 3 3 6);; 29 | 30 | // pg. 67 31 | // ------------------------------------------------------------------------- // 32 | // Example. // 33 | // ------------------------------------------------------------------------- // 34 | 35 | let [x; y; out; c] = List.map mk_index ["X"; "Y"; "OUT"; "C"];; 36 | // propexamples.p004 37 | ripplecarry x y c out 2;; 38 | 39 | // pg. 72 40 | // ------------------------------------------------------------------------- // 41 | // Examples. // 42 | // ------------------------------------------------------------------------- // 43 | 44 | // propexamples.p005 45 | tautology(prime 7);; 46 | 47 | // propexamples.p006 48 | tautology(prime 9);; 49 | 50 | // propexamples.p007 51 | tautology(prime 11);; 52 | -------------------------------------------------------------------------------- /Examples/qelim.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.fol 13 | open FSharpx.Books.AutomatedReasoning.skolem 14 | open FSharpx.Books.AutomatedReasoning.equal 15 | open FSharpx.Books.AutomatedReasoning.decidable 16 | open FSharpx.Books.AutomatedReasoning.qelim 17 | 18 | fsi.AddPrinter sprint_fol_formula 19 | 20 | // pg. 335 21 | // ------------------------------------------------------------------------- // 22 | // Examples. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | // qelim.p001 26 | quelim_dlo (parse @" 27 | forall x y. exists z. z < x /\ z < y") 28 | ;; 29 | 30 | // qelim.p002 31 | quelim_dlo (parse @" 32 | exists z. z < x /\ z < y") 33 | ;; 34 | 35 | // qelim.p003 36 | quelim_dlo (parse @" 37 | exists z. x < z /\ z < y") 38 | ;; 39 | 40 | // qelim.p004 41 | quelim_dlo (parse @" 42 | (forall x. x < a ==> x < b)") 43 | ;; 44 | 45 | // qelim.p005 46 | quelim_dlo (parse @" 47 | forall a b. (forall x. x < a ==> x < b) <=> a <= b") 48 | ;; 49 | 50 | // qelim.p006 51 | quelim_dlo (parse @" 52 | forall a b. (forall x. x < a <=> x < b) <=> a = b") 53 | ;; 54 | 55 | // qelim.p007 56 | quelim_dlo (parse @" 57 | exists x y z. forall u. 58 | x < x \/ ~x < u \/ (x < y /\ y < z /\ ~x < z)") 59 | ;; 60 | 61 | // ------------------------------------------------------------------------- // 62 | // More tests (not in the text). // 63 | // ------------------------------------------------------------------------- // 64 | 65 | // qelim.p008 66 | time quelim_dlo (parse @" 67 | forall x. exists y. x < y") 68 | ;; 69 | 70 | // qelim.p009 71 | time quelim_dlo (parse @" 72 | forall x y z. x < y /\ y < z ==> x < z") 73 | ;; 74 | 75 | // qelim.p010 76 | time quelim_dlo (parse @" 77 | forall x y. x < y \/ (x = y) \/ y < x") 78 | ;; 79 | 80 | // qelim.p011 81 | time quelim_dlo (parse @" 82 | exists x y. x < y /\ y < x") 83 | ;; 84 | 85 | // qelim.p012 86 | time quelim_dlo (parse @" 87 | forall x y. exists z. z < x /\ x < y") 88 | ;; 89 | 90 | // qelim.p013 91 | time quelim_dlo (parse @" 92 | exists z. z < x /\ x < y") 93 | ;; 94 | 95 | // qelim.p014 96 | time quelim_dlo (parse @" 97 | forall x y. exists z. z < x /\ z < y") 98 | ;; 99 | 100 | // qelim.p015 101 | time quelim_dlo (parse @" 102 | forall x y. x < y ==> exists z. x < z /\ z < y") 103 | ;; 104 | 105 | // qelim.p016 106 | time quelim_dlo (parse @" 107 | forall x y. ~(x = y) ==> exists u. u < x /\ (y < u \/ x < y)") 108 | ;; 109 | 110 | // qelim.p017 111 | time quelim_dlo (parse @" 112 | exists x. x = x") 113 | ;; 114 | 115 | // qelim.p018 116 | time quelim_dlo (parse @" 117 | exists x. x = x /\ x = y") 118 | ;; 119 | 120 | // qelim.p019 121 | time quelim_dlo (parse @" 122 | exists z. x < z /\ z < y") 123 | ;; 124 | 125 | // qelim.p020 126 | time quelim_dlo (parse @" 127 | exists z. x <= z /\ z <= y") 128 | ;; 129 | 130 | // qelim.p021 131 | time quelim_dlo (parse @" 132 | exists z. x < z /\ z <= y") 133 | ;; 134 | 135 | // qelim.p022 136 | time quelim_dlo (parse @" 137 | forall x y z. exists u. u < x /\ u < y /\ u < z") 138 | ;; 139 | 140 | // qelim.p023 141 | time quelim_dlo (parse @" 142 | forall y. x < y /\ y < z ==> w < z") 143 | ;; 144 | 145 | // qelim.p024 146 | time quelim_dlo (parse @" 147 | forall x y. x < y") 148 | ;; 149 | 150 | // qelim.p025 151 | time quelim_dlo (parse @" 152 | exists z. z < x /\ x < y") 153 | ;; 154 | 155 | // qelim.p026 156 | time quelim_dlo (parse @" 157 | forall a b. (forall x. x < a ==> x < b) <=> a <= b") 158 | ;; 159 | 160 | // qelim.p027 161 | time quelim_dlo (parse @" 162 | forall x. x < a ==> x < b") 163 | ;; 164 | 165 | // qelim.p028 166 | time quelim_dlo (parse @" 167 | forall x. x < a ==> x <= b") 168 | ;; 169 | 170 | // qelim.p029 171 | time quelim_dlo (parse @" 172 | forall a b. exists x. ~(x = a) \/ ~(x = b) \/ (a = b)") 173 | ;; 174 | 175 | // qelim.p030 176 | time quelim_dlo (parse @" 177 | forall x y. x <= y \/ x > y") 178 | ;; 179 | 180 | // qelim.p031 181 | time quelim_dlo (parse @" 182 | forall x y. x <= y \/ x < y") 183 | ;; 184 | -------------------------------------------------------------------------------- /Examples/real.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.initialization 10 | open FSharpx.Books.AutomatedReasoning.lib 11 | open FSharpx.Books.AutomatedReasoning.intro 12 | open FSharpx.Books.AutomatedReasoning.formulas 13 | open FSharpx.Books.AutomatedReasoning.prop 14 | open FSharpx.Books.AutomatedReasoning.fol 15 | open FSharpx.Books.AutomatedReasoning.skolem 16 | open FSharpx.Books.AutomatedReasoning.completion 17 | open FSharpx.Books.AutomatedReasoning.qelim 18 | open FSharpx.Books.AutomatedReasoning.cooper 19 | open FSharpx.Books.AutomatedReasoning.complex 20 | open FSharpx.Books.AutomatedReasoning.real 21 | 22 | fsi.AddPrinter sprint_fol_formula 23 | 24 | // pg. 375 25 | // ------------------------------------------------------------------------- // 26 | // First examples. // 27 | // ------------------------------------------------------------------------- // 28 | 29 | // real.p001 30 | real_qelim (parse @"exists x. x^4 + x^2 + 1 = 0");; 31 | 32 | // real.p002 33 | real_qelim (parse @"exists x. x^3 - x^2 + x - 1 = 0");; 34 | 35 | // real.p003 36 | real_qelim (parse @"exists x y. x^3 - x^2 + x - 1 = 0 /\ y^3 - y^2 + y - 1 = 0 /\ ~(x = y)");; 37 | 38 | // real.p004 39 | real_qelim (parse @"exists x. x^2 - 3 * x + 2 = 0 /\ 2 * x - 3 = 0");; 40 | 41 | // real.p005 42 | real_qelim (parse @"forall a f k. (forall e. k < e ==> f < a * e) ==> f <= a * k");; 43 | 44 | // real.p006 45 | real_qelim (parse @"exists x. a * x^2 + b * x + c = 0");; 46 | 47 | // real.p007 48 | real_qelim (parse @"forall a b c. (exists x. a * x^2 + b * x + c = 0) <=> b^2 >= 4 * a * c");; 49 | 50 | // real.p008 51 | real_qelim (parse @"forall a b c. (exists x. a * x^2 + b * x + c = 0) <=> a = 0 /\ (b = 0 ==> c = 0) \/ ~(a = 0) /\ b^2 >= 4 * a * c");; 52 | 53 | // pg. 377 54 | // ------------------------------------------------------------------------- // 55 | // Termination ordering for group theory completion. // 56 | // ------------------------------------------------------------------------- // 57 | 58 | // real.p009 59 | real_qelim (parse @"1 < 2 /\ (forall x. 1 < x ==> 1 < x^2) /\ (forall x y. 1 < x /\ 1 < y ==> 1 < x * (1 + 2 * y))");; 60 | 61 | // real.p010 62 | // Real: 00:00:31.254, CPU: 00:00:31.109, GC gen0: 169, gen1: 168, gen2: 1 63 | let eqs = complete_and_simplify ["1"; "*"; "i"] [(parse @"1 * x = x"); (parse @"i(x) * x = 1"); (parse @"(x * y) * z = x * y * z")];; 64 | 65 | // real.p011 66 | let fm = list_conj (List.map grpform eqs);; 67 | 68 | // real.p012 69 | runWithEnlargedStack (fun () -> 70 | real_qelim fm);; 71 | 72 | // real.p013 73 | real_qelim' (parse @"forall d. (exists c. forall a b. (a = d /\ b = c) \/ (a = c /\ b = 1) ==> a^2 = b) <=> d^4 = 1");; 74 | 75 | // Not in book. 76 | // ------------------------------------------------------------------------- // 77 | // Didn't seem worth it in the book, but monicization can help a lot. // 78 | // Now this is just set as an exercise. // 79 | // ------------------------------------------------------------------------- // 80 | 81 | let rec casesplit vars dun pols cont sgns = 82 | match pols with 83 | | [] -> monicize vars dun cont sgns 84 | | p::ops -> split_trichotomy sgns (head vars p) ( if is_constant vars p then delconst vars dun p ops cont else casesplit vars dun (behead vars p :: ops) cont ) ( if is_constant vars p then delconst vars dun p ops cont else casesplit vars (dun@[p]) ops cont ) 85 | 86 | and delconst vars dun p ops cont sgns = 87 | let cont' m = cont(List.map (insertat (List.length dun) (findsign sgns p)) m) 88 | casesplit vars dun ops cont' sgns 89 | 90 | and matrix vars pols cont sgns = 91 | if pols = [] then try cont [[]] with Failure _ -> False else 92 | let p = List.head(sort(decreasing (degree vars)) pols) 93 | let p' = poly_diff vars p 94 | let i = index p pols 95 | let qs = 96 | let p1,p2 = chop_list i pols 97 | p'::p1 @ List.tail p2 98 | let gs = List.map (pdivide_pos vars sgns p) qs 99 | let cont' m = cont(List.map (fun l -> insertat i (List.head l) (List.tail l)) m) 100 | casesplit vars [] (qs@gs) (dedmatrix cont') sgns 101 | 102 | and monicize vars pols cont sgns = 103 | let mols,swaps = List.unzip(List.map monic pols) 104 | let sols = setify mols 105 | let indices = List.map (fun p -> index p sols) mols 106 | let transform m = List.map2 (fun sw i -> swap sw (List.nth m i)) swaps indices 107 | let cont' mat = cont(List.map transform mat) 108 | matrix vars sols cont' sgns;; 109 | 110 | let basic_real_qelim vars = function 111 | | (Exists(x,p)) -> 112 | let pols = atom_union (function (R(a,[t;Fn("0",[])])) -> [t] | _ -> []) p 113 | let cont mat = if List.exists (fun m -> testform (List.zip pols m) p) mat 114 | then True else False 115 | casesplit (x::vars) [] pols cont init_sgns 116 | | _ -> failwith "malformed input";; 117 | 118 | let real_qelim = simplify << evalc << lift_qelim polyatom (simplify << evalc) basic_real_qelim;; 119 | 120 | let real_qelim' = simplify << evalc << lift_qelim polyatom (dnf << cnnf id << evalc) basic_real_qelim;; 121 | -------------------------------------------------------------------------------- /Examples/rewrite.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.fol 12 | open FSharpx.Books.AutomatedReasoning.resolution 13 | open FSharpx.Books.AutomatedReasoning.rewrite 14 | 15 | fsi.AddPrinter sprint_term 16 | 17 | // pg. 263 18 | // ------------------------------------------------------------------------- // 19 | // Example: 3 * 2 + 4 in successor notation. // 20 | // ------------------------------------------------------------------------- // 21 | 22 | // rewrite.p001 23 | rewrite 24 | [ 25 | parse @"0 + x = x"; 26 | parse @"S(x) + y = S(x + y)"; 27 | parse @"0 * x = 0"; 28 | parse @"S(x) * y = y + x * y"; 29 | ] 30 | (parset @"S(S(S(0))) * S(S(0)) + S(S(S(S(0))))");; 31 | -------------------------------------------------------------------------------- /Examples/skolem.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.fol 13 | open FSharpx.Books.AutomatedReasoning.skolem 14 | open FSharpx.Books.AutomatedReasoning.tableaux 15 | open FSharpx.Books.AutomatedReasoning.prolog 16 | open FSharpx.Books.AutomatedReasoning.meson 17 | open FSharpx.Books.AutomatedReasoning.skolem 18 | 19 | fsi.AddPrinter sprint_fol_formula 20 | 21 | // pg. 140 22 | // ------------------------------------------------------------------------- // 23 | // Example. // 24 | // ------------------------------------------------------------------------- // 25 | 26 | // skolem.p001 27 | simplify (parse @" 28 | (forall x y. P(x) \/ (P(y) /\ false)) 29 | ==> exists z. Q");; 30 | 31 | // pg. 141 32 | // ------------------------------------------------------------------------- // 33 | // Example of NNF function in action. // 34 | // ------------------------------------------------------------------------- // 35 | 36 | // skolem.p002 37 | nnf (parse @" 38 | (forall x. P(x)) 39 | ==> ((exists y. Q(y)) <=> exists z. P(z) /\ Q(z))");; 40 | 41 | // pg. 144 42 | // ------------------------------------------------------------------------- // 43 | // Example. // 44 | // ------------------------------------------------------------------------- // 45 | 46 | // skolem.p003 47 | pnf (parse @" 48 | (forall x. P(x) \/ R(y)) 49 | ==> exists y z. Q(y) \/ ~(exists z. P(z) /\ Q(z))");; 50 | 51 | // pg. 150 52 | // ------------------------------------------------------------------------- // 53 | // Example. // 54 | // ------------------------------------------------------------------------- // 55 | 56 | // skolem.p004 57 | skolemize (parse @" 58 | exists y. x < y 59 | ==> forall u. exists v. x * u < y * v");; 60 | 61 | // skolem.p005 62 | skolemize 63 | (parse @"forall x. P(x) 64 | ==> (exists y z. Q(y) \/ ~(exists z. P(z) /\ Q(z)))");; 65 | -------------------------------------------------------------------------------- /Examples/skolems.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.skolem 12 | open FSharpx.Books.AutomatedReasoning.skolems 13 | 14 | fsi.AddPrinter sprint_fol_formula 15 | 16 | // TODO: skolems is missing unit test. 17 | 18 | // pg. 226 19 | 20 | // skolems.p001 21 | skolemizes [ 22 | parse @"exists x y. x + y = 2"; 23 | parse @"forall x. exists y. x + 1 = y"; ];; -------------------------------------------------------------------------------- /Examples/stal.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.fol 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.propexamples 14 | open FSharpx.Books.AutomatedReasoning.defcnf 15 | open FSharpx.Books.AutomatedReasoning.dp 16 | open FSharpx.Books.AutomatedReasoning.stal 17 | 18 | fsi.AddPrinter sprint_prop_formula 19 | 20 | // pg. 94 21 | // ------------------------------------------------------------------------- // 22 | // An example. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | // stal.p001 26 | triggers (parse_prop_formula @"p <=> (q /\ r)");; 27 | 28 | // pg. 99 29 | // ------------------------------------------------------------------------- // 30 | // Examples. // 31 | // ------------------------------------------------------------------------- // 32 | 33 | // stal.p002 34 | // Real: 00:01:35.050, CPU: 00:01:34.906, GC gen0: 449, gen1: 281, gen2: 1 35 | time stalmarck (mk_adder_test 6 3);; 36 | -------------------------------------------------------------------------------- /Examples/unif.fsx: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | #load "initialization.fsx" 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.unif 12 | 13 | fsi.AddPrinter sprint_term 14 | 15 | // pg. 171 16 | // ------------------------------------------------------------------------- // 17 | // Examples. // 18 | // ------------------------------------------------------------------------- // 19 | 20 | // unify.p001 21 | unify_and_apply [(parset @"f(x,g(y))"),(parset @"f(f(z),w)")];; 22 | 23 | // unify.p002 24 | unify_and_apply [(parset @"f(x,y)"),(parset @"f(y,x)")];; 25 | 26 | // unify.p003 27 | // System.Exceptino: cyclic. - This is the expected result. 28 | //unify_and_apply [(parset @"f(x,g(y))"),(parset @"f(y,x)")];; 29 | 30 | // unify.p004 31 | unify_and_apply [(parset @"x_0"),(parset @"f(x_1,x_1)"); 32 | (parset @"x_1"),(parset @"f(x_2,x_2)"); 33 | (parset @"x_2"),(parset @"f(x_3,x_3)")];; 34 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/FSharpx.Books.AutomatedReasoning.Tests.VS10.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {841b64ff-8f9d-4d0e-9d4f-cd23b12b102d} 9 | Library 10 | FSharpx.Books.AutomatedReasoning.Tests 11 | FSharpx.Books.AutomatedReasoning.Tests 12 | v4.0 13 | FSharpx.Books.AutomatedReasoning.Tests.VS10 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | 3 25 | bin\Debug\FSharpx.Books.AutomatedReasoning.Tests.XML 26 | Project 27 | 28 | 29 | 30 | 31 | 62 32 | 33 | 34 | pdbonly 35 | true 36 | true 37 | bin\Release\ 38 | TRACE 39 | 3 40 | bin\Release\FSharpx.Books.AutomatedReasoning.Tests.XML 41 | 62 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | ..\packages\FSharp.Compatibility.OCaml.0.1.9\lib\net40\FSharp.Compatibility.OCaml.dll 92 | True 93 | 94 | 95 | ..\packages\FsUnit.1.1.1.0\Lib\Net40\FsUnit.NUnit.dll 96 | True 97 | 98 | 99 | 100 | 101 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 102 | True 103 | 104 | 105 | 106 | 107 | 108 | FSharpx.Books.AutomatedReasoning.VS10 109 | {cf42d6d9-75fd-4b6f-81ca-6db9cb2231a3} 110 | True 111 | 112 | 113 | 120 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/FSharpx.Books.AutomatedReasoning.Tests.VS11.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {841b64ff-8f9d-4d0e-9d4f-cd23b12b102d} 9 | Library 10 | FSharpx.Books.AutomatedReasoning.Tests 11 | FSharpx.Books.AutomatedReasoning.Tests 12 | v4.0 13 | FSharpx.Books.AutomatedReasoning.VS11 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | 3 25 | bin\Debug\FSharpx.Books.AutomatedReasoning.Tests.XML 26 | Project 27 | 28 | 29 | 30 | 31 | 32 | 33 | pdbonly 34 | true 35 | true 36 | bin\Release\ 37 | TRACE 38 | 3 39 | bin\Release\FSharpx.Books.AutomatedReasoning.Tests.XML 40 | 41 | 42 | 11 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | ..\packages\FSharp.Compatibility.OCaml.0.1.9\lib\net40\FSharp.Compatibility.OCaml.dll 92 | True 93 | 94 | 95 | ..\packages\FsUnit.1.1.1.0\Lib\Net40\FsUnit.NUnit.dll 96 | True 97 | 98 | 99 | 100 | 101 | ..\packages\NUnit.2.6.3\lib\nunit.framework.dll 102 | True 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | FSharpx.Books.AutomatedReasoning.VS11 111 | {cf42d6d9-75fd-4b6f-81ca-6db9cb2231a3} 112 | True 113 | 114 | 115 | 122 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/Option.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 3 | // (See "LICENSE.txt" for details.) // 4 | // ========================================================================= // 5 | 6 | module FSharpx.Books.AutomatedReasoning.Tests.Option 7 | 8 | open FSharpx.Books.AutomatedReasoning.lib 9 | open FSharpx.Books.AutomatedReasoning.formulas 10 | open FSharpx.Books.AutomatedReasoning.prop 11 | open FSharpx.Books.AutomatedReasoning.propexamples 12 | open FSharpx.Books.AutomatedReasoning.defcnf 13 | open FSharpx.Books.AutomatedReasoning.dp 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | // OCaml uses exceptions as a control flow. 19 | // In F# exceptions are expensive in terms of time. 20 | // Duning the intial conversion of the from OCaml to F# some of 21 | // the exceptions were converted to use F# Options. Later 22 | // it was decided to not use F# Options so as to keep 23 | // the F# code as close as possible to the OCaml code 24 | // since the goal was to help people learn from the book and 25 | // using F# Options can dramtically change the appearance of 26 | // the F# code for someone new to F# and/or OCaml. 27 | // 28 | // There is an optimized version of the F# code takes the coverted 29 | // F# code and make such optimizations. 30 | // 31 | // To show that exception as a control flow can be replaced 32 | // equivalently with F# Options, the following test are presented. 33 | // 34 | // In order to be able to test against the F# Options version of the code 35 | // for an F# equivelent, the the F# Options version of the code 36 | // is placed here for access by the test functions. 37 | 38 | let one_literal_rule_Option clauses = 39 | let findExpr cl = 40 | List.length cl = 1 41 | match List.tryFind findExpr clauses with 42 | | None -> None 43 | | Some value -> 44 | let u = List.head value 45 | let u' = negate u 46 | let clauses1 = List.filter (fun cl -> not (mem u cl)) clauses 47 | image (fun cl -> subtract cl [u']) clauses1 48 | |> Some 49 | 50 | let affirmative_negative_rule_Option clauses = 51 | let neg', pos = List.partition negative (unions clauses) 52 | let neg = image negate neg' 53 | let pos_only = subtract pos neg 54 | let neg_only = subtract neg pos 55 | let pureItem = union pos_only (image negate neg_only) 56 | if pureItem = [] then None 57 | else 58 | let clauses' = List.filter (fun cl -> intersect cl pureItem = []) clauses 59 | clauses' 60 | |> Some 61 | 62 | let rec dp_Option clauses = 63 | if clauses = [] then true 64 | elif mem [] clauses then false 65 | else 66 | match one_literal_rule_Option clauses with 67 | | Some value -> dp_Option value 68 | | None -> 69 | match affirmative_negative_rule_Option clauses with 70 | | Some value -> dp_Option value 71 | | None -> dp_Option (resolution_rule clauses) 72 | 73 | let rec dpll_Option clauses = 74 | if clauses = [] then true 75 | elif mem [] clauses then false 76 | else 77 | match one_literal_rule_Option clauses with 78 | | Some value -> dpll value 79 | | None -> 80 | match affirmative_negative_rule_Option clauses with 81 | | Some value -> dpll value 82 | | None -> 83 | let pvs = List.filter positive (unions clauses) 84 | let p = maximize (posneg_count clauses) pvs 85 | dpll (insert [p] clauses) || dpll (insert [negate p] clauses) 86 | 87 | let dpsat_Option fm = dp_Option (defcnfs fm) 88 | 89 | let dptaut_Option fm = not (dpsat_Option (Not fm)) 90 | 91 | let private options001Values : (formula * bool)[] = [| 92 | ( 93 | // idx 0 94 | // dp.p002 95 | (prime 11), 96 | true 97 | ); 98 | |] 99 | 100 | [] 101 | [] 102 | let ``options001 tests`` idx = 103 | let (prop_formula, _) = options001Values.[idx] 104 | let (_, result) = options001Values.[idx] 105 | dptaut_Option prop_formula 106 | |> should equal result 107 | dptaut prop_formula 108 | |> should equal result 109 | 110 | let private options002Values : (formula * bool)[] = [| 111 | ( 112 | // idx 0 113 | // dp.p003 114 | (prime 11), 115 | true 116 | ); 117 | |] 118 | 119 | [] 120 | [] 121 | let ``dplltaut tests`` idx = 122 | let (prop_formula, _) = options002Values.[idx] 123 | let (_, result) = options002Values.[idx] 124 | dptaut_Option prop_formula 125 | |> should equal result 126 | dplltaut prop_formula 127 | |> should equal result 128 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/bdd.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.bdd 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | open FSharpx.Books.AutomatedReasoning.bdd 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | let private bddtautValues : (formula * bool)[] = [| 19 | ( 20 | // idx 0 21 | // bdd.p001 22 | (mk_adder_test 4 2), 23 | true 24 | ); 25 | |] 26 | 27 | [] 28 | [] 29 | let ``bddtaut tests`` idx = 30 | let (formula, _) = bddtautValues.[idx] 31 | let (_, result) = bddtautValues.[idx] 32 | bddtaut formula 33 | |> should equal result 34 | 35 | let private ebddtautValues : (formula * bool)[] = [| 36 | ( 37 | // idx 0 38 | // bdd.p002 39 | (prime 101), 40 | true 41 | ); 42 | ( 43 | // idx 1 44 | // bdd.p003 45 | (mk_adder_test 9 5), 46 | true 47 | ); 48 | |] 49 | 50 | [] 51 | [] 52 | [] 53 | let ``ebddtaut tests`` idx = 54 | let (formula, _) = ebddtautValues.[idx] 55 | let (_, result) = ebddtautValues.[idx] 56 | ebddtaut formula 57 | |> should equal result 58 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/cong.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.cong 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.stal 13 | open FSharpx.Books.AutomatedReasoning.fol 14 | open FSharpx.Books.AutomatedReasoning.skolem 15 | open FSharpx.Books.AutomatedReasoning.meson 16 | open FSharpx.Books.AutomatedReasoning.equal 17 | open FSharpx.Books.AutomatedReasoning.cong 18 | 19 | open NUnit.Framework 20 | open FsUnit 21 | 22 | let private ccvalidValues : (string * bool)[] = [| 23 | ( 24 | // idx 0 25 | // cong.p001 26 | @"f(f(f(f(f(c))))) = c /\ f(f(f(c))) = c 27 | ==> f(c) = c \/ f(g(c)) = g(f(c))", 28 | true 29 | ) 30 | ( 31 | // idx 1 32 | // cong.p002 33 | @"f(f(f(f(c)))) = c /\ f(f(c)) = c 34 | ==> f(c) = c", 35 | false 36 | ) 37 | ( 38 | // idx 2 39 | // cong.p003 40 | @"f(a,b) = a 41 | ==> f(f(a,b), b) = a", 42 | true 43 | ) 44 | |] 45 | 46 | [] 47 | [] 48 | [] 49 | [] 50 | let ``ccvalid tests`` idx = 51 | let (formula, _) = ccvalidValues.[idx] 52 | let (_, result) = ccvalidValues.[idx] 53 | ccvalid (parse formula) 54 | |> should equal result 55 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/defcnf.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.defcnf 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.defcnf 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | let private cnfValues : (string * formula * string )[] = [| 19 | ( 20 | // idx 0 21 | // defcnf.p001 22 | @"p <=> (q <=> r)", 23 | And 24 | (Or (Atom (P "p"),Or (Atom (P "q"),Atom (P "r"))), 25 | And 26 | (Or (Atom (P "p"),Or (Not (Atom (P "q")),Not (Atom (P "r")))), 27 | And 28 | (Or (Atom (P "q"),Or (Not (Atom (P "p")),Not (Atom (P "r")))), 29 | Or (Atom (P "r"),Or (Not (Atom (P "p")),Not (Atom (P "q"))))))), 30 | @"<<(p \/ q \/ r) /\ (p \/ ~q \/ ~r) /\ (q \/ ~p \/ ~r) /\ (r \/ ~p \/ ~q)>>" 31 | ); 32 | |] 33 | 34 | [] 35 | [] 36 | let ``cnf tests`` idx = 37 | let (fm, _, _) = cnfValues.[idx] 38 | let (_, astResult, _) = cnfValues.[idx] 39 | let (_, _, stringResult) = cnfValues.[idx] 40 | let result = cnf (parse_prop_formula fm) 41 | result 42 | |> should equal astResult 43 | sprint_prop_formula result 44 | |> should equal stringResult 45 | 46 | let private defcnfOrigValues : (string * formula * string )[] = [| 47 | ( 48 | // idx 0 49 | // defcnf.p002 50 | @"(p \/ (q /\ ~r)) /\ s", 51 | And 52 | (Or (Atom (P "p"),Or (Atom (P "p_1"),Not (Atom (P "p_2")))), 53 | And 54 | (Or (Atom (P "p_1"),Or (Atom (P "r"),Not (Atom (P "q")))), 55 | And 56 | (Or (Atom (P "p_2"),Not (Atom (P "p"))), 57 | And 58 | (Or (Atom (P "p_2"),Not (Atom (P "p_1"))), 59 | And 60 | (Or (Atom (P "p_2"),Not (Atom (P "p_3"))), 61 | And 62 | (Atom (P "p_3"), 63 | And 64 | (Or 65 | (Atom (P "p_3"), 66 | Or (Not (Atom (P "p_2")),Not (Atom (P "s")))), 67 | And 68 | (Or (Atom (P "q"),Not (Atom (P "p_1"))), 69 | And 70 | (Or (Atom (P "s"),Not (Atom (P "p_3"))), 71 | Or 72 | (Not (Atom (P "p_1")),Not (Atom (P "r")))))))))))), 73 | @"<<(p \/ p_1 \/ ~p_2) /\ (p_1 \/ r \/ ~q) /\ (p_2 \/ ~p) /\ (p_2 \/ ~p_1) /\ " + 74 | "(p_2 \/ ~p_3) /\ p_3 /\ (p_3 \/ ~p_2 \/ ~s) /\ (q \/ ~p_1) /\ (s \/ ~p_3) /\ (~p_1 \/ ~r)>>" 75 | ); 76 | |] 77 | 78 | [] 79 | [] 80 | let ``defcnfOrig tests`` idx = 81 | let (fm, _, _) = defcnfOrigValues.[idx] 82 | let (_, astResult, _) = defcnfOrigValues.[idx] 83 | let (_, _, stringResult) = defcnfOrigValues.[idx] 84 | let result = defcnfOrig (parse_prop_formula fm) 85 | result 86 | |> should equal astResult 87 | sprint_prop_formula result 88 | |> should equal stringResult 89 | 90 | let private defcnfValues : (string * formula * string )[] = [| 91 | ( 92 | // idx 0 93 | // defcnf.p003 94 | @"(p \/ (q /\ ~r)) /\ s", 95 | And 96 | (Or (Atom (P "p"),Atom (P "p_1")), 97 | And 98 | (Or (Atom (P "p_1"),Or (Atom (P "r"),Not (Atom (P "q")))), 99 | And 100 | (Or (Atom (P "q"),Not (Atom (P "p_1"))), 101 | And 102 | (Atom (P "s"),Or (Not (Atom (P "p_1")),Not (Atom (P "r"))))))), 103 | @"<<(p \/ p_1) /\ (p_1 \/ r \/ ~q) /\ (q \/ ~p_1) /\ s /\ (~p_1 \/ ~r)>>" 104 | ); 105 | |] 106 | 107 | [] 108 | [] 109 | let ``defcnf tests`` idx = 110 | let (fm, _, _) = defcnfValues.[idx] 111 | let (_, astResult, _) = defcnfValues.[idx] 112 | let (_, _, stringResult) = defcnfValues.[idx] 113 | let result = defcnf (parse_prop_formula fm) 114 | result 115 | |> should equal astResult 116 | sprint_prop_formula result 117 | |> should equal stringResult 118 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/dp.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.dp 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | open FSharpx.Books.AutomatedReasoning.defcnf 14 | open FSharpx.Books.AutomatedReasoning.dp 15 | 16 | open NUnit.Framework 17 | open FsUnit 18 | 19 | let private dptautValues : (formula * bool)[] = [| 20 | ( 21 | // idx 0 22 | // dp.p002 23 | (prime 11), 24 | true 25 | ); 26 | |] 27 | 28 | [] 29 | [] 30 | let ``dptaut tests`` idx = 31 | let (prop_formula, _) = dptautValues.[idx] 32 | let (_, result) = dptautValues.[idx] 33 | dptaut prop_formula 34 | |> should equal result 35 | 36 | let private dplltautValues : (formula * bool)[] = [| 37 | ( 38 | // idx 0 39 | // dp.p003 40 | (prime 11), 41 | true 42 | ); 43 | |] 44 | 45 | [] 46 | [] 47 | let ``dplltaut tests`` idx = 48 | let (prop_formula, _) = dplltautValues.[idx] 49 | let (_, result) = dplltautValues.[idx] 50 | dplltaut prop_formula 51 | |> should equal result 52 | 53 | let private dplitautValues : (formula * bool)[] = [| 54 | ( 55 | // idx 0 56 | // dp.p004 57 | (prime 101), 58 | true 59 | ); 60 | ( 61 | // idx 1 62 | // dp.p006 63 | (prime 11), 64 | true 65 | ); 66 | |] 67 | 68 | [] 69 | [] 70 | [] 71 | let ``dplitaut tests`` idx = 72 | let (prop_formula, _) = dplitautValues.[idx] 73 | let (_, result) = dplitautValues.[idx] 74 | dplitaut prop_formula 75 | |> should equal result 76 | 77 | let private dplbtautValues : (formula * bool)[] = [| 78 | ( 79 | // idx 0 80 | // dp.p005 81 | (prime 101), 82 | true 83 | ); 84 | ( 85 | // idx 1 86 | // dp.p007 87 | (prime 11), 88 | true 89 | ); 90 | |] 91 | 92 | [] 93 | [] 94 | [] 95 | let ``dplbtaut tests`` idx = 96 | let (prop_formula, _) = dplbtautValues.[idx] 97 | let (_, result) = dplbtautValues.[idx] 98 | dplbtaut prop_formula 99 | |> should equal result 100 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/herbrand.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.herbrand 8 | 9 | open FSharpx.Books.AutomatedReasoning.initialization 10 | open FSharpx.Books.AutomatedReasoning.lib 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.prop 13 | open FSharpx.Books.AutomatedReasoning.dp 14 | open FSharpx.Books.AutomatedReasoning.fol 15 | open FSharpx.Books.AutomatedReasoning.skolem 16 | open FSharpx.Books.AutomatedReasoning.herbrand 17 | 18 | open NUnit.Framework 19 | open FsUnit 20 | 21 | let private gilmoreValues : (StackSize * string * int)[] = [| 22 | 23 | ( 24 | // idx 0 25 | // herbrand.p001 26 | Standard, 27 | @"exists x. forall y. P(x) ==> P(y)", 28 | 2 29 | ); 30 | ( 31 | // idx 1 32 | // herbrand.p003 33 | // Pelletier #24 34 | Standard, 35 | @" ~(exists x. U(x) /\ Q(x)) 36 | /\ (forall x. P(x) ==> Q(x) \/ R(x)) 37 | /\ ~(exists x. P(x) ==> (exists x. Q(x))) 38 | /\ (forall x. Q(x) 39 | /\ R(x) ==> U(x)) ==> (exists x. P(x) /\ R(x))", 40 | 1 41 | ); 42 | ( 43 | // idx 2 44 | // herbrand.p004 45 | // Pelletier #45 46 | Large, 47 | @"(forall x. P(x) 48 | /\ (forall y. G(y) /\ H(x,y) ==> J(x,y)) ==> (forall y. G(y) /\ H(x,y) ==> R(y))) 49 | /\ ~(exists y. L(y) /\ R(y)) 50 | /\ (exists x. P(x) /\ (forall y. H(x,y) ==> L(y)) 51 | /\ (forall y. G(y) /\ H(x,y) ==> J(x,y))) ==> (exists x. P(x) /\ ~(exists y. G(y) /\ H(x,y)))", 52 | 5 53 | ); 54 | ( 55 | // idx 3 56 | // herbrand.p005 57 | // Pelletier #20 58 | Standard, 59 | @"(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w)) 60 | ==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))", 61 | -99 62 | ); 63 | |] 64 | 65 | [] 66 | [] 67 | [] 68 | [] 69 | [] 70 | let ``gilmore tests`` (idx) = 71 | let (stackSize, _, _) = gilmoreValues.[idx] 72 | let (_, formula, _) = gilmoreValues.[idx] 73 | let (_, _, result) = gilmoreValues.[idx] 74 | match stackSize with 75 | | Standard -> 76 | gilmore (parse formula) 77 | | Large -> 78 | runWithEnlargedStack (fun () -> gilmore (parse formula)) 79 | |> should equal result 80 | 81 | let private davisputnamValues : (string * int)[] = [| 82 | ( 83 | // idx 0 84 | // herbrand.p006 85 | // Pelletier #20 86 | @"(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w)) 87 | ==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))", 88 | 19 89 | ); 90 | |] 91 | 92 | [] 93 | [] 94 | let ``davisputnam tests`` (idx) = 95 | let (formula, _) = davisputnamValues.[idx] 96 | let (_, result) = davisputnamValues.[idx] 97 | davisputnam (parse formula) 98 | |> should equal result 99 | 100 | let private davisputnam002Values : (string * int)[] = [| 101 | ( 102 | // idx 0 103 | // herbrand.p007 104 | // Pelletier #36 105 | @"(forall x. exists y. P(x,y)) 106 | /\ (forall x. exists y. G(x,y)) 107 | /\ (forall x y. P(x,y) \/ G(x,y) ==> (forall z. P(y,z) \/ G(y,z) ==> H(x,z))) 108 | ==> (forall x. exists y. H(x,y))", 109 | 3 110 | ); 111 | ( 112 | // idx 1 113 | // herbrand.p008 114 | // Pelletier #29 115 | @"(exists x. P(x)) /\ (exists x. G(x)) ==> 116 | ((forall x. P(x) ==> H(x)) /\ (forall x. G(x) ==> J(x)) <=> 117 | (forall x y. P(x) /\ G(y) ==> H(x) /\ J(y)))", 118 | 5 119 | ); 120 | |] 121 | 122 | [] 123 | [] 124 | [] 125 | let ``davisputnam002 tests`` (idx) = 126 | let (formula, _) = davisputnam002Values.[idx] 127 | let (_, result) = davisputnam002Values.[idx] 128 | davisputnam002 (parse formula) 129 | |> should equal result 130 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/intro.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.intro 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.intro 11 | 12 | open NUnit.Framework 13 | open FsUnit 14 | 15 | let private simplifyValues : (expression * expression)[] = [| 16 | ( 17 | // idx 0 18 | // intro.p002 19 | (Add (Mul (Add (Mul (Const 0, Var "x"), Const 1), Const 3), Const 12)), 20 | (Const 15) 21 | ); 22 | |] 23 | 24 | [] 25 | [] 26 | let ``simplify tests`` idx = 27 | let (expr, _) = simplifyValues.[idx] 28 | let (_, result) = simplifyValues.[idx] 29 | simplify expr 30 | |> should equal result 31 | 32 | let private lexValues : (string * string list)[] = [| 33 | ( 34 | // idx 0 35 | // intro.p003 36 | @"2*((var_1 + x') + 11)", 37 | ["2"; "*"; "("; "("; "var_1"; "+"; "x'"; ")"; "+"; "11"; ")"] 38 | ); 39 | ( 40 | // idx 1 41 | // intro.p004 42 | @"if //p1-- == *p2++) then f() else g()", 43 | ["if"; "//"; "p1"; "--"; "=="; "*"; "p2"; "++"; ")"; "then"; "f"; "("; ")"; "else"; "g"; "("; ")"] 44 | ); 45 | |] 46 | 47 | [] 48 | [] 49 | [] 50 | let ``lex tests`` idx = 51 | let (text, _) = lexValues.[idx] 52 | let (_, result) = lexValues.[idx] 53 | lex (explode text) 54 | |> should equal result 55 | 56 | let private parse_expValues : (string * expression)[] = [| 57 | ( 58 | // idx 0 59 | // intro.p005 60 | @"x + 1", 61 | (Add (Var "x",Const 1)) 62 | ); 63 | ( 64 | // idx 1 65 | // intro.p006 66 | @"(x1 + x2 + x3) * (1 + 2 + 3 * x + y)", 67 | (Mul (Add (Var "x1",Add (Var "x2",Var "x3")), 68 | Add (Const 1,Add (Const 2,Add (Mul (Const 3,Var "x"),Var "y"))))) 69 | ); 70 | ( 71 | // idx 2 72 | // intro.p008 73 | @"x + 3 * y", 74 | Add (Var "x",Mul (Const 3,Var "y")) 75 | ); 76 | ( 77 | // idx 3 78 | // intro.p009 79 | @"(x + 3) * y", 80 | Mul (Add (Var "x",Const 3),Var "y") 81 | ); 82 | ( 83 | // idx 4 84 | // intro.p010 85 | @"1 + 2 + 3", 86 | Add (Const 1,Add (Const 2,Const 3)) 87 | ); 88 | ( 89 | // idx 5 90 | // intro.p011 91 | @"((1 + 2) + 3) + 4", 92 | Add (Add (Add (Const 1,Const 2),Const 3),Const 4) 93 | ); 94 | ( 95 | // idx 6 96 | // intro.p012 97 | @"(x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10) * (y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8 + y9 + y10)", 98 | Mul (Add (Var "x1", Add (Var "x2", Add (Var "x3", Add (Var "x4", Add (Var "x5", Add (Var "x6", Add (Var "x7",Add (Var "x8",Add (Var "x9",Var "x10"))))))))), 99 | Add (Var "y1", Add (Var "y2", Add (Var "y3", Add (Var "y4", Add (Var "y5", Add (Var "y6", Add (Var "y7",Add (Var "y8",Add (Var "y9",Var "y10")))))))))) 100 | ); 101 | |] 102 | 103 | [] 104 | [] 105 | [] 106 | [] 107 | [] 108 | [] 109 | [] 110 | [] 111 | let ``parse_exp tests`` idx = 112 | let (text, _) = parse_expValues.[idx] 113 | let (_, result) = parse_expValues.[idx] 114 | parse_exp text 115 | |> should equal result 116 | 117 | let private string_of_expValues : (string * string)[] = [| 118 | ( 119 | // idx 0 120 | // intro.p007 121 | "x + 3 * y", 122 | "(x + (3 * y))" 123 | ); 124 | |] 125 | 126 | [] 127 | [] 128 | let ``string_of_exp tests`` idx = 129 | let (text, _) = string_of_expValues.[idx] 130 | let (_, result) = string_of_expValues.[idx] 131 | string_of_exp (parse_exp text) 132 | |> should equal result -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/lcfprop.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.lcfprop 8 | 9 | open FSharpx.Books.AutomatedReasoning.fol 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.lcf 12 | open FSharpx.Books.AutomatedReasoning.lcfprop 13 | 14 | open NUnit.Framework 15 | open FsUnit 16 | 17 | let private lcfpropValues : (string * thm * string )[] = [| 18 | ( 19 | // idx 0 20 | // Pelletier #12 21 | // lcfprop.p003 22 | @"((p <=> q) <=> r) <=> (p <=> (q <=> r))", 23 | Iff 24 | (Iff (Iff (Atom (R ("p",[])),Atom (R ("q",[]))),Atom (R ("r",[]))), 25 | Iff (Atom (R ("p",[])),Iff (Atom (R ("q",[])),Atom (R ("r",[]))))), 26 | @"|- ((p <=> q) <=> r) <=> p <=> q <=> r" 27 | ); 28 | ( 29 | // idx 1 30 | // Pelletier #16 31 | // lcfprop.p001 32 | @"(p ==> q) \/ (q ==> p)", 33 | Or 34 | (Imp (Atom (R ("p",[])),Atom (R ("q",[]))), 35 | Imp (Atom (R ("q",[])),Atom (R ("p",[])))), 36 | @"|- (p ==> q) \/ (q ==> p)" 37 | ); 38 | ( 39 | // idx 2 40 | // Harrison #02 - Equations within equations 41 | // lcfprop.p002 42 | @"p /\ q <=> ((p <=> q) <=> p \/ q)", 43 | Iff 44 | (And (Atom (R ("p",[])),Atom (R ("q",[]))), 45 | Iff 46 | (Iff (Atom (R ("p",[])),Atom (R ("q",[]))), 47 | Or (Atom (R ("p",[])),Atom (R ("q",[]))))), 48 | @"|- p /\ q <=> (p <=> q) <=> p \/ q" 49 | ); 50 | |] 51 | 52 | [] 53 | [] 54 | [] 55 | [] 56 | let ``lcftaut ast tests`` idx = 57 | let (formula, _, _) = lcfpropValues.[idx] 58 | let (_, ast_result, _) = lcfpropValues.[idx] 59 | lcftaut (parse formula) 60 | |> should equal ast_result 61 | 62 | [] 63 | [] 64 | [] 65 | [] 66 | let ``lcftaut pp tests`` idx = 67 | let (formula, _, _) = lcfpropValues.[idx] 68 | let (_, _, pretty_printer_result) = lcfpropValues.[idx] 69 | lcftaut (parse formula) 70 | |> sprint_thm 71 | |> should equal pretty_printer_result 72 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/order.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.order 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.order 12 | 13 | open NUnit.Framework 14 | open FsUnit 15 | 16 | let s = parset "f(x,x,x)" 17 | let t = parset "g(x,y)" 18 | 19 | // order.p001 20 | [] 21 | let ``termsize 1``() = 22 | termsize s > termsize t 23 | |> should be True 24 | 25 | // ------------------------------------------------------------------------- // 26 | // This fails the rewrite properties. // 27 | // ------------------------------------------------------------------------- // 28 | 29 | let i = "y" |=> parset "f(x,x,x)" 30 | 31 | // order.p002 32 | [] 33 | let ``termsize 2``() = 34 | termsize (tsubst i s) > termsize (tsubst i t) 35 | |> should be False 36 | 37 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/paramodulation.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.paramodulation 8 | 9 | open FSharpx.Books.AutomatedReasoning.fol 10 | open FSharpx.Books.AutomatedReasoning.paramodulation 11 | 12 | open NUnit.Framework 13 | open FsUnit 14 | 15 | 16 | let private paramodulationValues : (string * bool list)[] = [| 17 | ( 18 | // idx 0 19 | // paramodulation.p001 20 | @"(forall x. f(f(x)) = f(x)) /\ (forall x. exists y. f(y) = x) 21 | ==> forall x. f(x) = x", 22 | [true] 23 | ); 24 | |] 25 | 26 | [] 27 | [] 28 | let ``paramodulation tests`` idx = 29 | let (formula, _) = paramodulationValues.[idx] 30 | let (_, result) = paramodulationValues.[idx] 31 | paramodulation (parse formula) 32 | |> should equal result 33 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/rewrite.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.rewrite 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.fol 12 | open FSharpx.Books.AutomatedReasoning.resolution 13 | open FSharpx.Books.AutomatedReasoning.rewrite 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | 19 | let private rewriteValues : (formula list * term * term * string)[] = [| 20 | ( 21 | // idx 0 22 | // rewrite.p001 23 | [parse @"0 + x = x"; 24 | parse @"S(x) + y = S(x + y)"; 25 | parse @"0 * x = 0"; 26 | parse @"S(x) * y = y + x * y"], 27 | (parset @"S(S(S(0))) * S(S(0)) + S(S(S(S(0))))"), 28 | Fn 29 | ("S", 30 | [Fn 31 | ("S", 32 | [Fn 33 | ("S", 34 | [Fn 35 | ("S", 36 | [Fn 37 | ("S", 38 | [Fn 39 | ("S", 40 | [Fn 41 | ("S", 42 | [Fn 43 | ("S",[Fn ("S",[Fn ("S",[Fn ("0",[])])])])])])])])])])]), 44 | @"<<|S(S(S(S(S(S(S(S(S(S(0))))))))))|>>" 45 | ) 46 | |] 47 | 48 | [] 49 | [] 50 | let ``rewrite tests`` idx = 51 | let (eqs, _, _, _) = rewriteValues.[idx] 52 | let (_, tm, _, _) = rewriteValues.[idx] 53 | let (_, _, astResult, _) = rewriteValues.[idx] 54 | let (_, _, _, stringResult) = rewriteValues.[idx] 55 | let result = rewrite eqs tm 56 | result 57 | |> should equal result 58 | sprint_term result 59 | |> should equal stringResult 60 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/skolem.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.skolem 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.fol 13 | open FSharpx.Books.AutomatedReasoning.skolem 14 | open FSharpx.Books.AutomatedReasoning.tableaux 15 | open FSharpx.Books.AutomatedReasoning.prolog 16 | open FSharpx.Books.AutomatedReasoning.meson 17 | open FSharpx.Books.AutomatedReasoning.skolem 18 | 19 | open NUnit.Framework 20 | open FsUnit 21 | 22 | let private simplifyValues : (string * formula * string)[] = [| 23 | ( 24 | // idx 0 25 | // skolem.p001 26 | @"(forall x y. P(x) \/ (P(y) /\ false)) 27 | ==> exists z. Q", 28 | Imp (Forall ("x",Atom (R ("P",[Var "x"]))),Atom (R ("Q",[]))), 29 | @"<<(forall x. P(x)) ==> Q>>" 30 | ) 31 | |] 32 | 33 | [] 34 | [] 35 | let ``simplify tests`` idx = 36 | let (formula, _, _) = simplifyValues.[idx] 37 | let (_, astResult, _) = simplifyValues.[idx] 38 | let (_, _, stringResult) = simplifyValues.[idx] 39 | let result = simplify (parse formula) 40 | result 41 | |> should equal astResult 42 | sprint_fol_formula result 43 | |> should equal stringResult 44 | 45 | 46 | let private nnfValues : (string * formula * string)[] = [| 47 | ( 48 | // idx 0 49 | // skolem.p002 50 | @"(forall x. P(x)) 51 | ==> ((exists y. Q(y)) <=> exists z. P(z) /\ Q(z))", 52 | Or 53 | (Exists ("x",Not (Atom (R ("P",[Var "x"])))), 54 | Or 55 | (And 56 | (Exists ("y",Atom (R ("Q",[Var "y"]))), 57 | Exists 58 | ("z", 59 | And (Atom (R ("P",[Var "z"])),Atom (R ("Q",[Var "z"]))))), 60 | And 61 | (Forall ("y",Not (Atom (R ("Q",[Var "y"])))), 62 | Forall 63 | ("z", 64 | Or 65 | (Not (Atom (R ("P",[Var "z"]))), 66 | Not (Atom (R ("Q",[Var "z"])))))))), 67 | @"<<(exists x. ~P(x)) \/ (exists y. Q(y)) /\ (exists z. P(z) /\ Q(z)) \/ (forall y. ~Q(y)) /\ (forall z. ~P(z) \/ ~Q(z))>>" 68 | ) 69 | |] 70 | 71 | [] 72 | [] 73 | let ``nnf tests`` idx = 74 | let (formula, _, _) = nnfValues.[idx] 75 | let (_, astResult, _) = nnfValues.[idx] 76 | let (_, _, stringResult) = nnfValues.[idx] 77 | let result = nnf (parse formula) 78 | result 79 | |> should equal astResult 80 | sprint_fol_formula result 81 | |> should equal stringResult 82 | 83 | 84 | let private pnfValues : (string * formula * string)[] = [| 85 | ( 86 | // idx 0 87 | // skolem.p003 88 | @"(forall x. P(x) \/ R(y)) 89 | ==> exists y z. Q(y) \/ ~(exists z. P(z) /\ Q(z))", 90 | Exists 91 | ("x", 92 | Forall 93 | ("z", 94 | Or 95 | (And 96 | (Not (Atom (R ("P",[Var "x"]))), 97 | Not (Atom (R ("R",[Var "y"])))), 98 | Or 99 | (Atom (R ("Q",[Var "x"])), 100 | Or 101 | (Not (Atom (R ("P",[Var "z"]))), 102 | Not (Atom (R ("Q",[Var "z"])))))))), 103 | @"<>" 104 | ) 105 | |] 106 | 107 | [] 108 | [] 109 | let ``pnf tests`` idx = 110 | let (formula, _, _) = pnfValues.[idx] 111 | let (_, astResult, _) = pnfValues.[idx] 112 | let (_, _, stringResult) = pnfValues.[idx] 113 | let result = pnf (parse formula) 114 | result 115 | |> should equal astResult 116 | sprint_fol_formula result 117 | |> should equal stringResult 118 | 119 | let private skolemizeValues : (string * formula * string)[] = [| 120 | ( 121 | // idx 0 122 | // skolem.p004 123 | @"exists y. x < y 124 | ==> forall u. exists v. x * u < y * v", 125 | Or 126 | (Not (Atom (R ("<",[Var "x"; Fn ("f_y",[Var "x"])]))), 127 | Atom 128 | (R ("<", 129 | [Fn ("*",[Var "x"; Var "u"]); 130 | Fn 131 | ("*",[Fn ("f_y",[Var "x"]); Fn ("f_v",[Var "u"; Var "x"])])]))), 132 | @"<<~x >" 133 | ) 134 | ( 135 | // idx 1 136 | // skolem.p005 137 | @"forall x. P(x) 138 | ==> (exists y z. Q(y) \/ ~(exists z. P(z) /\ Q(z)))", 139 | Or 140 | (Not (Atom (R ("P",[Var "x"]))), 141 | Or 142 | (Atom (R ("Q",[Fn ("c_y",[])])), 143 | Or 144 | (Not (Atom (R ("P",[Var "z"]))),Not (Atom (R ("Q",[Var "z"])))))), 145 | @"<<~P(x) \/ Q(c_y) \/ ~P(z) \/ ~Q(z)>>" 146 | ) 147 | |] 148 | 149 | [] 150 | [] 151 | [] 152 | let ``skolemize tests`` idx = 153 | let (formula, _, _) = skolemizeValues.[idx] 154 | let (_, astResult, _) = skolemizeValues.[idx] 155 | let (_, _, stringResult) = skolemizeValues.[idx] 156 | let result = skolemize (parse formula) 157 | result 158 | |> should equal astResult 159 | sprint_fol_formula result 160 | |> should equal stringResult 161 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/skolems.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.skolems 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.formulas 12 | open FSharpx.Books.AutomatedReasoning.skolem 13 | open FSharpx.Books.AutomatedReasoning.skolems 14 | 15 | open NUnit.Framework 16 | open FsUnit 17 | 18 | let private skolemizesValues : (formula list * formula list)[] = [| 19 | ( 20 | // idx 0 21 | // skolems.p001 22 | [parse @"exists x y. x + y = 2"; 23 | parse @"forall x. exists y. x + 1 = y"; ], 24 | [Atom 25 | (R ("=", 26 | [Fn ("old_+",[Fn ("c_x",[]); Fn ("c_y",[])]); Fn ("old_2",[])])); 27 | Forall 28 | ("x", 29 | Atom 30 | (R ("=", 31 | [Fn ("old_+",[Var "x"; Fn ("old_1",[])]); 32 | Fn ("f_y",[Var "x"])])))] 33 | ); 34 | |] 35 | 36 | [] 37 | [] 38 | let ``skolemizes tests`` idx = 39 | let (formula, _) = skolemizesValues.[idx] 40 | let (_, result) = skolemizesValues.[idx] 41 | skolemizes formula 42 | |> should equal result -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/stal.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.stal 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.formulas 11 | open FSharpx.Books.AutomatedReasoning.prop 12 | open FSharpx.Books.AutomatedReasoning.propexamples 13 | open FSharpx.Books.AutomatedReasoning.defcnf 14 | open FSharpx.Books.AutomatedReasoning.dp 15 | open FSharpx.Books.AutomatedReasoning.stal 16 | open FSharp.Compatibility.OCaml 17 | open Num 18 | 19 | open NUnit.Framework 20 | open FsUnit 21 | 22 | let private triggersValues : (string * ((formula * formula) * (formula * formula) list) list)[] = [| 23 | ( 24 | // idx 0 25 | // stal.p001 26 | @"p <=> (q /\ r)", 27 | [((Atom (P "p"), formula.True), [(Atom (P "q"), formula.True); (Atom (P "r"), formula.True)]); 28 | ((Atom (P "q"), formula.True), [(Atom (P "r"), Atom (P "p"))]); 29 | ((Atom (P "q"), Not formula.True), [(Atom (P "p"), Not formula.True)]); 30 | ((Atom (P "q"), Not (Atom (P "p"))), [(Atom (P "p"), Not formula.True); (Atom (P "r"), Atom (P "p"))]); 31 | ((Atom (P "r"), formula.True), [(Atom (P "q"), Atom (P "p"))]); 32 | ((Atom (P "r"), Atom (P "q")), [(Atom (P "q"), Atom (P "p"))]); 33 | ((Atom (P "r"), Not formula.True), [(Atom (P "p"), Not formula.True)]); 34 | ((Atom (P "r"), Not (Atom (P "p"))), [(Atom (P "p"), Not formula.True); (Atom (P "q"), Atom (P "p"))]); 35 | ((Atom (P "r"), Not (Atom (P "q"))), [(Atom (P "p"), Not formula.True)]) 36 | ] 37 | ); 38 | |] 39 | 40 | [] 41 | [] 42 | let triggers idx = 43 | let (formula, _) = triggersValues.[idx] 44 | let (_, result) = triggersValues.[idx] 45 | triggers (parse_prop_formula formula) 46 | |> should equal result 47 | 48 | let private stalmarckValues : (formula * bool)[] = [| 49 | ( 50 | // idx 0 51 | // stal.p002 52 | (mk_adder_test 6 3), 53 | true 54 | ); 55 | ( 56 | // idx 1 57 | // stal.p003 58 | (mk_adder_test 2 1), 59 | true 60 | ); 61 | |] 62 | 63 | [] 64 | [] 65 | [] 66 | let ``stalmarck tests`` idx = 67 | let (formula, _) = stalmarckValues.[idx] 68 | let (_, result) = stalmarckValues.[idx] 69 | stalmarck formula 70 | |> should equal result 71 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.Tests/unif.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.Tests.unif 8 | 9 | open FSharpx.Books.AutomatedReasoning.lib 10 | open FSharpx.Books.AutomatedReasoning.fol 11 | open FSharpx.Books.AutomatedReasoning.unif 12 | 13 | open NUnit.Framework 14 | open FsUnit 15 | 16 | let private unify_and_applyValues : ((term * term) list * (term * term) list)[] = [| 17 | ( 18 | // idx 0 19 | // unif.p001 20 | [(parset @"f(x,g(y))"),(parset @"f(f(z),w)")], 21 | [(Fn ("f",[Fn ("f",[Var "z"]); Fn ("g",[Var "y"])]), 22 | Fn ("f",[Fn ("f",[Var "z"]); Fn ("g",[Var "y"])]))] 23 | ); 24 | ( 25 | // idx 1 26 | // unify.p002 27 | [(parset @"f(x,y)"),(parset @"f(y,x)")], 28 | [(Fn ("f",[Var "y"; Var "y"]), Fn ("f",[Var "y"; Var "y"]))] 29 | ); 30 | ( 31 | // idx 2 32 | // unify.p003 33 | [(parset @"f(x,g(y))"),(parset @"f(y,x)")], 34 | [(Fn ("f",[Fn ("f",[Var "z"]); Fn ("g",[Var "y"])]), 35 | Fn ("f",[Fn ("f",[Var "z"]); Fn ("g",[Var "y"])]))] 36 | ); 37 | ( 38 | // idx 3 39 | // unify.p004 40 | [(parset @"x_0"),(parset @"f(x_1,x_1)"); 41 | (parset @"x_1"),(parset @"f(x_2,x_2)"); 42 | (parset @"x_2"),(parset @"f(x_3,x_3)")], 43 | [(Fn 44 | ("f", 45 | [Fn 46 | ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])]); 47 | Fn 48 | ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])])]), 49 | Fn 50 | ("f", 51 | [Fn 52 | ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])]); 53 | Fn 54 | ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])])])); 55 | (Fn ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])]), 56 | Fn ("f",[Fn ("f",[Var "x_3"; Var "x_3"]); Fn ("f",[Var "x_3"; Var "x_3"])])); 57 | (Fn ("f",[Var "x_3"; Var "x_3"]), Fn ("f",[Var "x_3"; Var "x_3"]))] 58 | ); 59 | |] 60 | 61 | [] 62 | [] 63 | [] 64 | [, 66 | ExpectedMessage = "cyclic")>] 67 | [] 68 | let ``unify_and_apply tests`` (idx) = 69 | let (eqs, _) = unify_and_applyValues.[idx] 70 | let (_, result) = unify_and_applyValues.[idx] 71 | unify_and_apply eqs 72 | |> should equal result 73 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.VS10.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpx.Books.AutomatedReasoning.VS10", "FSharpx.Books.AutomatedReasoning\FSharpx.Books.AutomatedReasoning.VS10.fsproj", "{CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}" 5 | EndProject 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F3B5AF8C-FE04-4366-B04F-290C5F5519EB}" 7 | ProjectSection(SolutionItems) = preProject 8 | Examples\bdd.fsx = Examples\bdd.fsx 9 | Examples\combining.fsx = Examples\combining.fsx 10 | Examples\completion.fsx = Examples\completion.fsx 11 | Examples\complex.fsx = Examples\complex.fsx 12 | Examples\cong.fsx = Examples\cong.fsx 13 | Examples\cooper.fsx = Examples\cooper.fsx 14 | Examples\decidable.fsx = Examples\decidable.fsx 15 | Examples\defcnf.fsx = Examples\defcnf.fsx 16 | Examples\dp.fsx = Examples\dp.fsx 17 | Examples\eqelim.fsx = Examples\eqelim.fsx 18 | Examples\equal.fsx = Examples\equal.fsx 19 | Examples\fol.fsx = Examples\fol.fsx 20 | Examples\folderived.fsx = Examples\folderived.fsx 21 | Examples\geom.fsx = Examples\geom.fsx 22 | Examples\grobner.fsx = Examples\grobner.fsx 23 | Examples\herbrand.fsx = Examples\herbrand.fsx 24 | Examples\init_all.fsx = Examples\init_all.fsx 25 | Examples\initialization.fsx = Examples\initialization.fsx 26 | Examples\interpolation.fsx = Examples\interpolation.fsx 27 | Examples\intro.fsx = Examples\intro.fsx 28 | Examples\lcffol.fsx = Examples\lcffol.fsx 29 | Examples\lcfprop.fsx = Examples\lcfprop.fsx 30 | Examples\lib.fsx = Examples\lib.fsx 31 | Examples\limitations.fsx = Examples\limitations.fsx 32 | Examples\meson.fsx = Examples\meson.fsx 33 | Examples\order.fsx = Examples\order.fsx 34 | Examples\paramodulation.fsx = Examples\paramodulation.fsx 35 | Examples\prolog.fsx = Examples\prolog.fsx 36 | Examples\prop.fsx = Examples\prop.fsx 37 | Examples\propexamples.fsx = Examples\propexamples.fsx 38 | Examples\qelim.fsx = Examples\qelim.fsx 39 | Examples\real.fsx = Examples\real.fsx 40 | Examples\resolution.fsx = Examples\resolution.fsx 41 | Examples\rewrite.fsx = Examples\rewrite.fsx 42 | Examples\skolem.fsx = Examples\skolem.fsx 43 | Examples\skolems.fsx = Examples\skolems.fsx 44 | Examples\stal.fsx = Examples\stal.fsx 45 | Examples\tableaux.fsx = Examples\tableaux.fsx 46 | Examples\tactics.fsx = Examples\tactics.fsx 47 | Examples\unif.fsx = Examples\unif.fsx 48 | EndProjectSection 49 | EndProject 50 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2D15CC03-9404-4759-BF38-39159F3D85CD}" 51 | ProjectSection(SolutionItems) = preProject 52 | .nuget\NuGet.Config = .nuget\NuGet.Config 53 | .nuget\NuGet.exe = .nuget\NuGet.exe 54 | .nuget\NuGet.targets = .nuget\NuGet.targets 55 | EndProjectSection 56 | EndProject 57 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpx.Books.AutomatedReasoning.Tests.VS10", "FSharpx.Books.AutomatedReasoning.Tests\FSharpx.Books.AutomatedReasoning.Tests.VS10.fsproj", "{841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}" 58 | EndProject 59 | Global 60 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 61 | Debug|Any CPU = Debug|Any CPU 62 | Debug|Mixed Platforms = Debug|Mixed Platforms 63 | Debug|x86 = Debug|x86 64 | Release|Any CPU = Release|Any CPU 65 | Release|Mixed Platforms = Release|Mixed Platforms 66 | Release|x86 = Release|x86 67 | EndGlobalSection 68 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 69 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 70 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Any CPU.Build.0 = Debug|Any CPU 71 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 72 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 73 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|x86.ActiveCfg = Debug|Any CPU 74 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 77 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU 78 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|x86.ActiveCfg = Release|Any CPU 79 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 80 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Any CPU.Build.0 = Debug|Any CPU 81 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 82 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 83 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|x86.ActiveCfg = Debug|Any CPU 84 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 87 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Mixed Platforms.Build.0 = Release|Any CPU 88 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|x86.ActiveCfg = Release|Any CPU 89 | EndGlobalSection 90 | GlobalSection(SolutionProperties) = preSolution 91 | HideSolutionNode = FALSE 92 | EndGlobalSection 93 | EndGlobal 94 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning.VS11.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{F3B5AF8C-FE04-4366-B04F-290C5F5519EB}" 5 | ProjectSection(SolutionItems) = preProject 6 | Examples\bdd.fsx = Examples\bdd.fsx 7 | Examples\combining.fsx = Examples\combining.fsx 8 | Examples\completion.fsx = Examples\completion.fsx 9 | Examples\complex.fsx = Examples\complex.fsx 10 | Examples\cong.fsx = Examples\cong.fsx 11 | Examples\cooper.fsx = Examples\cooper.fsx 12 | Examples\decidable.fsx = Examples\decidable.fsx 13 | Examples\defcnf.fsx = Examples\defcnf.fsx 14 | Examples\dp.fsx = Examples\dp.fsx 15 | Examples\eqelim.fsx = Examples\eqelim.fsx 16 | Examples\equal.fsx = Examples\equal.fsx 17 | Examples\fol.fsx = Examples\fol.fsx 18 | Examples\folderived.fsx = Examples\folderived.fsx 19 | Examples\geom.fsx = Examples\geom.fsx 20 | Examples\grobner.fsx = Examples\grobner.fsx 21 | Examples\herbrand.fsx = Examples\herbrand.fsx 22 | Examples\init_all.fsx = Examples\init_all.fsx 23 | Examples\initialization.fsx = Examples\initialization.fsx 24 | Examples\interpolation.fsx = Examples\interpolation.fsx 25 | Examples\intro.fsx = Examples\intro.fsx 26 | Examples\lcffol.fsx = Examples\lcffol.fsx 27 | Examples\lcfprop.fsx = Examples\lcfprop.fsx 28 | Examples\lib.fsx = Examples\lib.fsx 29 | Examples\limitations.fsx = Examples\limitations.fsx 30 | Examples\meson.fsx = Examples\meson.fsx 31 | Examples\order.fsx = Examples\order.fsx 32 | Examples\paramodulation.fsx = Examples\paramodulation.fsx 33 | Examples\prolog.fsx = Examples\prolog.fsx 34 | Examples\prop.fsx = Examples\prop.fsx 35 | Examples\propexamples.fsx = Examples\propexamples.fsx 36 | Examples\qelim.fsx = Examples\qelim.fsx 37 | Examples\real.fsx = Examples\real.fsx 38 | Examples\resolution.fsx = Examples\resolution.fsx 39 | Examples\rewrite.fsx = Examples\rewrite.fsx 40 | Examples\skolem.fsx = Examples\skolem.fsx 41 | Examples\skolems.fsx = Examples\skolems.fsx 42 | Examples\stal.fsx = Examples\stal.fsx 43 | Examples\tableaux.fsx = Examples\tableaux.fsx 44 | Examples\tactics.fsx = Examples\tactics.fsx 45 | Examples\unif.fsx = Examples\unif.fsx 46 | EndProjectSection 47 | EndProject 48 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2D15CC03-9404-4759-BF38-39159F3D85CD}" 49 | ProjectSection(SolutionItems) = preProject 50 | .nuget\NuGet.Config = .nuget\NuGet.Config 51 | .nuget\NuGet.exe = .nuget\NuGet.exe 52 | .nuget\NuGet.targets = .nuget\NuGet.targets 53 | EndProjectSection 54 | EndProject 55 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpx.Books.AutomatedReasoning.VS11", "FSharpx.Books.AutomatedReasoning\FSharpx.Books.AutomatedReasoning.VS11.fsproj", "{CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}" 56 | EndProject 57 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpx.Books.AutomatedReasoning.Tests.VS11", "FSharpx.Books.AutomatedReasoning.Tests\FSharpx.Books.AutomatedReasoning.Tests.VS11.fsproj", "{841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}" 58 | EndProject 59 | Global 60 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 61 | Debug|Any CPU = Debug|Any CPU 62 | Debug|Mixed Platforms = Debug|Mixed Platforms 63 | Debug|x86 = Debug|x86 64 | Release|Any CPU = Release|Any CPU 65 | Release|Mixed Platforms = Release|Mixed Platforms 66 | Release|x86 = Release|x86 67 | EndGlobalSection 68 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 69 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 70 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Any CPU.Build.0 = Debug|Any CPU 71 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 72 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 73 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Debug|x86.ActiveCfg = Debug|Any CPU 74 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 77 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU 78 | {CF42D6D9-75FD-4B6F-81CA-6DB9CB2231A3}.Release|x86.ActiveCfg = Release|Any CPU 79 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 80 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Any CPU.Build.0 = Debug|Any CPU 81 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 82 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 83 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Debug|x86.ActiveCfg = Debug|Any CPU 84 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 87 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|Mixed Platforms.Build.0 = Release|Any CPU 88 | {841B64FF-8F9D-4D0E-9D4F-CD23B12B102D}.Release|x86.ActiveCfg = Release|Any CPU 89 | EndGlobalSection 90 | GlobalSection(SolutionProperties) = preSolution 91 | HideSolutionNode = FALSE 92 | EndGlobalSection 93 | EndGlobal 94 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/FSharpx.Books.AutomatedReasoning.VS10.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {cf42d6d9-75fd-4b6f-81ca-6db9cb2231a3} 9 | Library 10 | FSharpx.Books.AutomatedReasoning 11 | FSharpx.Books.AutomatedReasoning 12 | v4.0 13 | FSharpx.Books.AutomatedReasoning.VS10 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | bin\Debug\ 23 | TRACE;DEBUG 24 | 3 25 | bin\Debug\FSharpx.Books.AutomatedReasoning.XML 26 | 25,62 27 | 28 | 29 | pdbonly 30 | true 31 | true 32 | bin\Release\ 33 | TRACE 34 | 3 35 | bin\Release\FSharpx.Books.AutomatedReasoning.XML 36 | 25,62 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | ..\packages\FSharp.Compatibility.OCaml.0.1.9\lib\net40\FSharp.Compatibility.OCaml.dll 88 | True 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 103 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/FSharpx.Books.AutomatedReasoning.VS11.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {cf42d6d9-75fd-4b6f-81ca-6db9cb2231a3} 9 | Library 10 | FSharpx.Books.AutomatedReasoning 11 | FSharpx.Books.AutomatedReasoning 12 | v4.0 13 | FSharpx.Books.AutomatedReasoning.VS11 14 | ..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | false 22 | bin\Debug\ 23 | TRACE;DEBUG 24 | 3 25 | bin\Debug\FSharpx.Books.AutomatedReasoning.XML 26 | 25 27 | 28 | 29 | pdbonly 30 | true 31 | true 32 | bin\Release\ 33 | TRACE 34 | 3 35 | bin\Release\FSharpx.Books.AutomatedReasoning.XML 36 | 37 | 38 | 11 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ..\packages\FSharp.Compatibility.OCaml.0.1.9\lib\net40\FSharp.Compatibility.OCaml.dll 89 | True 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/cong.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.cong 8 | 9 | open formulas 10 | open prop 11 | open fol 12 | open skolem 13 | open equal 14 | 15 | // pg. 249 16 | // ========================================================================= // 17 | // Simple congruence closure. // 18 | // ========================================================================= // 19 | 20 | let rec subterms tm = 21 | match tm with 22 | | Fn (f, args) -> 23 | List.foldBack (union << subterms) args [tm] 24 | | _ -> [tm] 25 | 26 | // pg. 250 27 | // ------------------------------------------------------------------------- // 28 | // Test whether subterms are congruent under an equivalence. // 29 | // ------------------------------------------------------------------------- // 30 | 31 | let congruent eqv (s, t) = 32 | match s, t with 33 | | Fn (f, a1), Fn (g, a2) when f = g -> 34 | List.forall2 (equivalent eqv) a1 a2 35 | | _ -> false 36 | 37 | // pg. 251 38 | // ------------------------------------------------------------------------- // 39 | // Merging of terms, with congruence closure. // 40 | // ------------------------------------------------------------------------- // 41 | 42 | let rec emerge (s, t) (eqv, pfn) = 43 | let s' = canonize eqv s 44 | let t' = canonize eqv t 45 | if s' = t' then 46 | eqv, pfn 47 | else 48 | let sp = tryapplyl pfn s' 49 | let tp = tryapplyl pfn t' 50 | let eqv' = equate (s, t) eqv 51 | let st' = canonize eqv' s' 52 | let pfn' = (st' |-> union sp tp) pfn 53 | List.foldBack (fun (u, v) (eqv, pfn) -> 54 | if congruent eqv (u, v) then emerge (u, v) (eqv, pfn) 55 | else eqv, pfn) 56 | (allpairs (fun u v -> (u, v)) sp tp) (eqv', pfn') 57 | 58 | // pg. 253 59 | // ------------------------------------------------------------------------- // 60 | // Satisfiability of conjunction of ground equations and inequations. // 61 | // ------------------------------------------------------------------------- // 62 | 63 | let predecessors t pfn = 64 | match t with 65 | | Fn (f, a) -> 66 | List.foldBack (fun s f -> (s |-> insert t (tryapplyl f s)) f) (setify a) pfn 67 | | _ -> pfn 68 | 69 | let ccsatisfiable fms = 70 | let pos, neg = List.partition positive fms 71 | let eqps = List.map dest_eq pos 72 | let eqns = List.map (dest_eq << negate) neg 73 | let pfn = 74 | let lrs = 75 | List.map fst eqps 76 | @ List.map snd eqps 77 | @ List.map fst eqns 78 | @ List.map snd eqns 79 | List.foldBack predecessors (unions (List.map subterms lrs)) undefined 80 | let eqv, _ = List.foldBack emerge eqps (unequal, pfn) 81 | List.forall (fun (l, r) -> 82 | not <| equivalent eqv l r) eqns 83 | 84 | // pg. 253 85 | // ------------------------------------------------------------------------- // 86 | // Validity checking a universal formula. // 87 | // ------------------------------------------------------------------------- // 88 | 89 | let ccvalid fm = 90 | let fms = simpdnf (askolemize (Not (generalize fm))) 91 | not (List.exists ccsatisfiable fms) 92 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/defcnf.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.defcnf 8 | 9 | open LanguagePrimitives 10 | open FSharp.Compatibility.OCaml.Num 11 | 12 | open intro 13 | open formulas 14 | open prop 15 | 16 | // ========================================================================= // 17 | // Definitional CNF. // 18 | // ========================================================================= // 19 | 20 | // pg. 75 21 | // ------------------------------------------------------------------------- // 22 | // Make a stylized variable and update the index. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | let mkprop (n : num) = 26 | let name = sprintf "p_%O" n 27 | Atom (P name), n + (num_of_int 1) 28 | 29 | // pg. 75 30 | // ------------------------------------------------------------------------- // 31 | // Core definitional CNF procedure. // 32 | // ------------------------------------------------------------------------- // 33 | 34 | let rec maincnf (fm, defs, n as trip) = 35 | match fm with 36 | | And (p, q) -> 37 | defstep mk_and (p, q) trip 38 | | Or (p, q) -> 39 | defstep mk_or (p, q) trip 40 | | Iff (p, q) -> 41 | defstep mk_iff (p, q) trip 42 | | _ -> trip 43 | 44 | and defstep op (p, q) (fm, defs, n) = 45 | let fm1, defs1, n1 = maincnf (p, defs, n) 46 | let fm2, defs2, n2 = maincnf (q, defs1, n1) 47 | let fm' = op fm1 fm2 48 | try fst(apply defs2 fm'), defs2, n2 49 | with _ -> 50 | let v, n3 = mkprop n2 51 | v, (fm' |-> (v, Iff (v, fm'))) defs2, n3 52 | 53 | // pg. 76 54 | // ------------------------------------------------------------------------- // 55 | // Make n large enough that "v_m" won't clash with s for any m >= n // 56 | // ------------------------------------------------------------------------- // 57 | 58 | let max_varindex pfx s (n : num) = 59 | let m = String.length pfx 60 | let l = String.length s 61 | if l <= m || s.[0..m] <> pfx then n else 62 | let s' = s.[m.. (l - m)] 63 | if List.forall numeric (explode s') then 64 | max n (num_of_string s') 65 | else n 66 | 67 | // pg. 77 68 | // ------------------------------------------------------------------------- // 69 | // Overall definitional CNF. // 70 | // ------------------------------------------------------------------------- // 71 | 72 | let mk_defcnf fn fm = 73 | let fm' = nenf fm 74 | let n = GenericOne + overatoms (max_varindex "p_" << pname) fm' GenericZero 75 | let fm'', defs, _ = fn (fm', undefined, n) 76 | let deflist = List.map (snd << snd) (graph defs) 77 | unions <| simpcnf fm'' :: List.map simpcnf deflist 78 | 79 | let defcnfOrig fm = 80 | mk_defcnf maincnf fm 81 | |> List.map list_disj 82 | |> list_conj 83 | 84 | // pg. 78 85 | // ------------------------------------------------------------------------- // 86 | // Version tweaked to exploit initial structure. // 87 | // ------------------------------------------------------------------------- // 88 | 89 | let subcnf sfn op (p, q) (fm, defs, n) = 90 | let fm1, defs1, n1 = sfn (p, defs, n) 91 | let fm2, defs2, n2 = sfn (q, defs1, n1) 92 | op fm1 fm2, defs2, n2 93 | 94 | let rec orcnf (fm, defs, n as trip) = 95 | match fm with 96 | | Or (p, q) -> 97 | subcnf orcnf mk_or (p,q) trip 98 | | _ -> maincnf trip 99 | 100 | let rec andcnf (fm, defs, n as trip) = 101 | match fm with 102 | | And (p, q) -> 103 | subcnf andcnf mk_and (p,q) trip 104 | | _ -> orcnf trip 105 | 106 | let defcnfs fm = 107 | mk_defcnf andcnf fm 108 | 109 | let defcnf fm = 110 | defcnfs fm 111 | |> List.map list_disj 112 | |> list_conj 113 | 114 | // pg. 78 115 | // ------------------------------------------------------------------------- // 116 | // Version that guarantees 3-CNF. // 117 | // ------------------------------------------------------------------------- // 118 | 119 | let rec andcnf3 (fm, defs, n as trip) = 120 | match fm with 121 | | And (p, q) -> 122 | subcnf andcnf3 mk_and (p, q) trip 123 | | _ -> maincnf trip 124 | 125 | let defcnf3 fm = 126 | mk_defcnf andcnf3 fm 127 | |> List.map list_disj 128 | |> list_conj 129 | 130 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/eqelim.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.eqelim 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open defcnf 13 | open dp 14 | open stal 15 | open bdd 16 | open fol 17 | open skolem 18 | open herbrand 19 | open unif 20 | open tableaux 21 | open resolution 22 | open prolog 23 | open meson 24 | open skolems 25 | open equal 26 | open cong 27 | open rewrite 28 | open order 29 | open completion 30 | 31 | // ========================================================================= // 32 | // Equality elimination including Brand transformation and relatives. // 33 | // ========================================================================= // 34 | 35 | // pg.291 36 | // ------------------------------------------------------------------------- // 37 | // Brand's S and T modifications on clauses. // 38 | // ------------------------------------------------------------------------- // 39 | 40 | let rec modify_S cl = 41 | try 42 | let (s,t) = tryfind dest_eq cl 43 | let eq1 = mk_eq s t 44 | let eq2 = mk_eq t s 45 | let sub = modify_S (subtract cl [eq1]) 46 | List.map (insert eq1) sub @ List.map (insert eq2) sub 47 | with 48 | Failure _ -> [cl] 49 | 50 | let rec modify_T cl = 51 | match cl with 52 | | [] -> [] 53 | | (Atom (R ("=", [s; t])) as eq) :: ps -> 54 | let ps' = modify_T ps 55 | let w = Var (variant "w" (List.foldBack (union << fv) ps' (fv eq))) 56 | Not (mk_eq t w) :: (mk_eq s w) :: ps' 57 | | p :: ps -> 58 | p :: (modify_T ps) 59 | 60 | 61 | // pg. 294 62 | // ------------------------------------------------------------------------- // 63 | // Finding nested non-variable subterms. // 64 | // ------------------------------------------------------------------------- // 65 | 66 | // val is_nonvar : term -> bool 67 | let is_nonvar = function 68 | | Var x -> false 69 | | _ -> true 70 | 71 | let find_nestnonvar tm = 72 | match tm with 73 | | Var x -> failwith "findnvsubt" 74 | | Fn (f, args) -> 75 | List.find is_nonvar args 76 | 77 | let rec find_nvsubterm fm = 78 | match fm with 79 | | Atom (R ("=", [s; t])) -> 80 | tryfind find_nestnonvar [s;t] 81 | | Atom (R (p, args)) -> 82 | List.find is_nonvar args 83 | | Not p -> 84 | find_nvsubterm p 85 | 86 | // pg. 295 87 | // ------------------------------------------------------------------------- // 88 | // Replacement (substitution for non-variable) in term and literal. // 89 | // ------------------------------------------------------------------------- // 90 | 91 | let rec replacet rfn tm = 92 | try apply rfn tm 93 | with Failure _ -> 94 | match tm with 95 | | Fn (f, args) -> 96 | Fn (f, List.map (replacet rfn) args) 97 | | _ -> tm 98 | 99 | let replace rfn = 100 | onformula (replacet rfn) 101 | 102 | // pg. 295 103 | // ------------------------------------------------------------------------- // 104 | // E-modification of a clause. // 105 | // ------------------------------------------------------------------------- // 106 | 107 | let rec emodify fvs cls = 108 | try 109 | let t = tryfind find_nvsubterm cls 110 | let w = variant "w" fvs 111 | let cls' = List.map (replace (t |=> Var w)) cls 112 | emodify (w :: fvs) (Not (mk_eq t (Var w)) :: cls') 113 | with Failure _ -> 114 | cls 115 | 116 | let modify_E cls = emodify (List.foldBack (union << fv) cls []) cls 117 | 118 | // pg. 296 119 | // ------------------------------------------------------------------------- // 120 | // Overall Brand transformation. // 121 | // ------------------------------------------------------------------------- // 122 | 123 | let brand cls = 124 | let cls1 = List.map modify_E cls 125 | let cls2 = List.foldBack (union << modify_S) cls1 [] 126 | [mk_eq (Var "x") (Var "x")] :: (List.map modify_T cls2) 127 | 128 | // pg. 296 129 | // ------------------------------------------------------------------------- // 130 | // Incorporation into MESON. // 131 | // ------------------------------------------------------------------------- // 132 | 133 | let bpuremeson fm = 134 | let cls = brand (simpcnf (specialize (pnf fm))) 135 | let rules = List.foldBack ((@) << contrapositives) cls [] 136 | deepen (fun n -> 137 | mexpand002 rules [] False id (undefined, n, 0) 138 | |> ignore 139 | n) 0 140 | 141 | let bmeson fm = 142 | let fm1 = askolemize (Not (generalize fm)) 143 | List.map (bpuremeson << list_conj) (simpdnf fm1) 144 | 145 | // Moved from section - Older stuff not now in the text 146 | // to here because it is still in the text. EGT 147 | let emeson fm = meson002 (equalitize fm) 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/equal.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.equal 8 | 9 | open formulas 10 | open fol 11 | open skolem 12 | 13 | // 14 | // pg. 235 15 | // ========================================================================= // 16 | // First order logic with equality. // 17 | // ========================================================================= // 18 | 19 | let is_eq = function 20 | | Atom (R ("=", _)) -> true 21 | | _ -> false 22 | 23 | let mk_eq s t = 24 | Atom (R ("=", [s; t])) 25 | 26 | let dest_eq fm = 27 | match fm with 28 | | Atom (R ("=", [s;t])) -> 29 | s, t 30 | | _ -> 31 | failwith "dest_eq: not an equation" 32 | 33 | let lhs eq = fst <| dest_eq eq 34 | let rhs eq = snd <| dest_eq eq 35 | 36 | // pg. 239 37 | // ------------------------------------------------------------------------- // 38 | // The set of predicates in a formula. // 39 | // ------------------------------------------------------------------------- // 40 | 41 | let rec predicates fm = 42 | atom_union (fun (R (p, a)) -> [p, List.length a]) fm 43 | 44 | // pg. 239 45 | // ------------------------------------------------------------------------- // 46 | // Code to generate equality axioms for functions. // 47 | // ------------------------------------------------------------------------- // 48 | 49 | let function_congruence (f, n) = 50 | if n = 0 then [] 51 | else 52 | let argnames_x = List.map (fun n -> "x" + (string n)) (1 -- n) 53 | let argnames_y = List.map (fun n -> "y" + (string n)) (1 -- n) 54 | let args_x = List.map (fun x -> Var x) argnames_x 55 | let args_y = List.map (fun x -> Var x) argnames_y 56 | let ant = List.reduceBack mk_and (List.map2 mk_eq args_x args_y) 57 | let con = mk_eq (Fn (f, args_x)) (Fn (f, args_y)) 58 | [List.foldBack mk_forall (argnames_x @ argnames_y) (Imp (ant, con))] 59 | 60 | // pg. 240 61 | // ------------------------------------------------------------------------- // 62 | // And for predicates. // 63 | // ------------------------------------------------------------------------- // 64 | 65 | let predicate_congruence (p, n) = 66 | if n = 0 then [] 67 | else 68 | let argnames_x = List.map (fun n -> "x" + (string n)) (1 -- n) 69 | let argnames_y = List.map (fun n -> "y" + (string n)) (1 -- n) 70 | let args_x = List.map (fun x -> Var x) argnames_x 71 | let args_y = List.map (fun x -> Var x) argnames_y 72 | let ant = List.reduceBack mk_and (List.map2 mk_eq args_x args_y) 73 | let con = Imp (Atom (R (p, args_x)), Atom (R (p, args_y))) 74 | [List.foldBack mk_forall (argnames_x @ argnames_y) (Imp (ant, con))] 75 | 76 | // pg. 240 77 | // ------------------------------------------------------------------------- // 78 | // Hence implement logic with equality just by adding equality "axioms". // 79 | // ------------------------------------------------------------------------- // 80 | 81 | let equivalence_axioms = 82 | [(parse "forall x. x = x"); (parse "forall x y z. x = y /\ x = z ==> y = z")] 83 | 84 | let equalitize fm = 85 | let allpreds = predicates fm 86 | if not (mem ("=", 2) allpreds) then fm 87 | else 88 | let preds = subtract allpreds ["=", 2] 89 | let funcs = functions fm 90 | let axioms = List.foldBack (union << function_congruence) funcs 91 | (List.foldBack (union << predicate_congruence) preds 92 | equivalence_axioms) 93 | Imp (List.reduceBack mk_and axioms, fm) 94 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/herbrand.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.herbrand 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open dp 13 | open fol 14 | open skolem 15 | 16 | // ========================================================================= // 17 | // Relation between FOL and propositonal logic; Herbrand theorem. // 18 | // ========================================================================= // 19 | // 20 | // pg. 151 21 | // ------------------------------------------------------------------------- // 22 | // Propositional valuation. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | let pholds d fm = eval fm (fun p -> d (Atom p)) 26 | 27 | // pg. 156 28 | // ------------------------------------------------------------------------- // 29 | // Get the constants for Herbrand base, adding nullary one if necessary. // 30 | // ------------------------------------------------------------------------- // 31 | 32 | let herbfuns fm = 33 | let cns, fns = List.partition (fun (_, ar) -> ar = 0) (functions fm) 34 | if cns = [] then ["c", 0], fns else cns, fns 35 | 36 | // pg. 159 37 | // ------------------------------------------------------------------------- // 38 | // Enumeration of ground terms and m-tuples, ordered by total fns. // 39 | // ------------------------------------------------------------------------- // 40 | 41 | let rec groundterms cntms funcs n = 42 | if n = 0 then cntms else 43 | List.foldBack (fun (f, m) l -> 44 | List.map (fun args -> 45 | Fn (f, args)) 46 | (groundtuples cntms funcs (n - 1) m) @ l) 47 | funcs [] 48 | 49 | and groundtuples cntms funcs n m = 50 | if m = 0 then 51 | if n = 0 then [[]] 52 | else [] 53 | else 54 | List.foldBack (fun k l -> 55 | allpairs (fun h t -> h :: t) 56 | (groundterms cntms funcs k) 57 | (groundtuples cntms funcs (n - k) (m - 1)) @ l) 58 | (0 -- n) [] 59 | 60 | // pg. 160 61 | // ------------------------------------------------------------------------- // 62 | // Iterate modifier "mfn" over ground terms till "tfn" fails. // 63 | // ------------------------------------------------------------------------- // 64 | 65 | let rec herbloop mfn tfn fl0 cntms funcs fvs n fl tried tuples = 66 | printfn "%i ground instances tried; %i items in list." 67 | (List.length tried) (List.length fl) 68 | 69 | match tuples with 70 | | [] -> 71 | let newtups = groundtuples cntms funcs n (List.length fvs) 72 | herbloop mfn tfn fl0 cntms funcs fvs (n + 1) fl tried newtups 73 | | tup :: tups -> 74 | let fl' = mfn fl0 (subst (fpf fvs tup)) fl 75 | if not (tfn fl') then tup :: tried 76 | else herbloop mfn tfn fl0 cntms funcs fvs n fl' (tup :: tried) tups 77 | 78 | // pg. 160 79 | // ------------------------------------------------------------------------- // 80 | // Hence a simple Gilmore-type procedure. // 81 | // ------------------------------------------------------------------------- // 82 | 83 | let gilmore_loop = 84 | let mfn djs0 ifn djs = 85 | List.filter (non trivial) (distrib (image (image ifn) djs0) djs) 86 | herbloop mfn (fun djs -> djs <> []) 87 | 88 | let gilmore fm = 89 | let sfm = skolemize (Not (generalize fm)) 90 | let fvs = fv sfm 91 | let consts, funcs = herbfuns sfm 92 | let cntms = image (fun (c, _) -> Fn (c, [])) consts 93 | List.length (gilmore_loop (simpdnf sfm) cntms funcs fvs 0 [[]] [] []) 94 | 95 | // pg. 163 96 | // ------------------------------------------------------------------------- // 97 | // The Davis-Putnam procedure for first order logic. // 98 | // ------------------------------------------------------------------------- // 99 | 100 | let dp_mfn cjs0 ifn cjs = union (image (image ifn) cjs0) cjs 101 | 102 | let dp_loop = herbloop dp_mfn dpll 103 | 104 | let davisputnam fm = 105 | let sfm = skolemize (Not (generalize fm)) 106 | let fvs = fv sfm 107 | let consts, funcs = herbfuns sfm 108 | let cntms = image (fun (c, _) -> Fn (c, [])) consts 109 | List.length (dp_loop (simpcnf sfm) cntms funcs fvs 0 [] [] []) 110 | 111 | // pg. 163 112 | // ------------------------------------------------------------------------- // 113 | // Try to cut out useless instantiations in final result. // 114 | // ------------------------------------------------------------------------- // 115 | 116 | let rec dp_refine cjs0 fvs dunno need = 117 | match dunno with 118 | | [] -> need 119 | | cl :: dknow -> 120 | let mfn = dp_mfn cjs0 << subst << fpf fvs 121 | let need' = 122 | if dpll (List.foldBack mfn (need @ dknow) []) then cl :: need 123 | else need 124 | dp_refine cjs0 fvs dknow need' 125 | 126 | let dp_refine_loop cjs0 cntms funcs fvs n cjs tried tuples = 127 | let tups = dp_loop cjs0 cntms funcs fvs n cjs tried tuples 128 | dp_refine cjs0 fvs tups [] 129 | 130 | // pg. 163 131 | // ------------------------------------------------------------------------- // 132 | // Show how few of the instances we really need. Hence unification! // 133 | // ------------------------------------------------------------------------- // 134 | 135 | let davisputnam002 fm = 136 | let sfm = skolemize (Not (generalize fm)) 137 | let fvs = fv sfm 138 | let consts,funcs = herbfuns sfm 139 | let cntms = image (fun (c, _) -> Fn (c, [])) consts 140 | List.length (dp_refine_loop (simpcnf sfm) cntms funcs fvs 0 [] [] []) 141 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/initialization.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 3 | // (See "LICENSE.txt" for details.) // 4 | // ========================================================================= // 5 | 6 | /// Misc functions to set up a nice environment. 7 | [] 8 | module FSharpx.Books.AutomatedReasoning.initialization 9 | 10 | type StackSize = 11 | | Standard 12 | | Large 13 | 14 | /// The greatest maximum-stack-size that should be used 15 | /// with the 'runWithStackFrame' function. 16 | let [] STACK_LIMIT = 16777216;; 17 | 18 | /// Run a function with a custom maximum stack size. 19 | /// This is necessary for some functions to execute 20 | /// without raising a StackOverflowException. 21 | let runWithCustomStackSize maxStackSize fn = 22 | // Preconditions 23 | if maxStackSize < 1048576 then 24 | invalidArg "stackSize" "Functions should not be executed with a \ 25 | maximum stack size of less than 1048576 bytes (1MB)." 26 | elif maxStackSize > STACK_LIMIT then 27 | invalidArg "stackSize" "The maximum size of the stack frame should \ 28 | not exceed 16777216 bytes (16MB)." 29 | 30 | /// Holds the return value of the function. 31 | let result = ref Unchecked.defaultof<'T> 32 | 33 | // Create a thread with the specified maximum stack size, 34 | // then immediately execute the function on it. 35 | let thread = System.Threading.Thread ((fun () -> result := fn()), maxStackSize) 36 | thread.Start () 37 | 38 | // Wait for the function/thread to finish and return the result. 39 | thread.Join () 40 | !result;; 41 | 42 | /// Runs a function within a thread which has an enlarged maximum-stack-size. 43 | let inline runWithEnlargedStack fn = 44 | runWithCustomStackSize STACK_LIMIT fn;; -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/interpolation.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | // ========================================================================= // 8 | // Implementation/proof of the Craig-Robinson interpolation theorem. // 9 | // // 10 | // This is based on the proof in Kreisel & Krivine, which works very nicely // 11 | // in our context. // 12 | // ========================================================================= // 13 | 14 | module FSharpx.Books.AutomatedReasoning.interpolation 15 | 16 | open FSharp.Compatibility.OCaml.Num 17 | 18 | open intro 19 | open formulas 20 | open prop 21 | open defcnf 22 | open dp 23 | open stal 24 | open bdd 25 | open fol 26 | open skolem 27 | open herbrand 28 | open unif 29 | open tableaux 30 | open resolution 31 | open prolog 32 | open meson 33 | open skolems 34 | open equal 35 | open cong 36 | open rewrite 37 | open order 38 | open completion 39 | open eqelim 40 | open paramodulation 41 | open decidable 42 | open qelim 43 | open cooper 44 | open complex 45 | open real 46 | open grobner 47 | open geom 48 | 49 | // pg. 428 50 | // ------------------------------------------------------------------------- // 51 | // Interpolation for propositional logic. // 52 | // ------------------------------------------------------------------------- // 53 | 54 | let pinterpolate p q = 55 | let orify a r = Or (psubst (a |=> False) r, psubst (a |=> True) r) 56 | psimplify (List.foldBack orify (subtract (atoms p) (atoms q)) p) 57 | 58 | // pg. 429 59 | // ------------------------------------------------------------------------- // 60 | // Relation-symbol interpolation for universal closed formulas. // 61 | // ------------------------------------------------------------------------- // 62 | 63 | let urinterpolate p q = 64 | let fm = specialize (prenex (And (p, q))) 65 | let fvs = fv fm 66 | let consts, funcs = herbfuns fm 67 | let cntms = List.map (fun (c, _) -> Fn (c, [])) consts 68 | let tups = dp_refine_loop (simpcnf fm) cntms funcs fvs 0 [] [] [] 69 | let fmis = List.map (fun tup -> subst (fpf fvs tup) fm) tups 70 | let ps, qs = List.unzip (List.map (fun (And (p, q)) -> p, q) fmis) 71 | pinterpolate (list_conj (setify ps)) (list_conj (setify qs)) 72 | 73 | // pg. 432 74 | // ------------------------------------------------------------------------- // 75 | // Pick the topmost terms starting with one of the given function symbols. // 76 | // ------------------------------------------------------------------------- // 77 | 78 | let rec toptermt fns tm = 79 | match tm with 80 | | Var x -> [] 81 | | Fn (f, args) -> 82 | if mem (f, List.length args) fns then [tm] 83 | else List.foldBack (union << toptermt fns) args [] 84 | 85 | let topterms fns = 86 | atom_union (fun (R (p, args)) -> List.foldBack (union << toptermt fns) args []) 87 | 88 | // pg. 433 89 | // ------------------------------------------------------------------------- // 90 | // Interpolation for arbitrary universal formulas. // 91 | // ------------------------------------------------------------------------- // 92 | 93 | let uinterpolate p q = 94 | let rec fp = functions p 95 | and fq = functions q 96 | let rec simpinter tms n c = 97 | match tms with 98 | | [] -> c 99 | | (Fn (f, args) as tm) :: otms -> 100 | let v = "v_" + (string n) 101 | let c' = replace (tm |=> Var v) c 102 | let c'' = 103 | if mem (f, List.length args) fp 104 | then Exists (v, c') 105 | else Forall (v, c') 106 | simpinter otms (n + 1) c'' 107 | let c = urinterpolate p q 108 | let tts = topterms (union (subtract fp fq) (subtract fq fp)) c 109 | let tms = sort (decreasing termsize) tts 110 | simpinter tms 1 c 111 | 112 | // pg. 434 113 | // ------------------------------------------------------------------------- // 114 | // Now lift to arbitrary formulas with no common free variables. // 115 | // ------------------------------------------------------------------------- // 116 | 117 | let cinterpolate p q = 118 | let fm = nnf (And (p, q)) 119 | let rec efm = List.foldBack mk_exists (fv fm) fm 120 | and fns = List.map fst (functions fm) 121 | let And (p', q'), _ = skolem efm fns 122 | uinterpolate p' q' 123 | 124 | // pg. 434 125 | // ------------------------------------------------------------------------- // 126 | // Now to completely arbitrary formulas. // 127 | // ------------------------------------------------------------------------- // 128 | 129 | let interpolate p q = 130 | let rec vs = List.map (fun v -> Var v) (intersect (fv p) (fv q)) 131 | and fns = functions (And (p, q)) 132 | let n = List.foldBack (max_varindex "c_" << fst) fns (Int 0) + (Int 1) 133 | let cs = List.map (fun i -> Fn ("c_" + i.ToString(), [])) (n --- (n + Int (List.length vs - 1))) 134 | let rec fn_vc = fpf vs cs 135 | and fn_cv = fpf cs vs 136 | let rec p' = replace fn_vc p 137 | and q' = replace fn_vc q 138 | replace fn_cv (cinterpolate p' q') 139 | 140 | // pg. 435 141 | // ------------------------------------------------------------------------- // 142 | // Lift to logic with equality. // 143 | // ------------------------------------------------------------------------- // 144 | 145 | let einterpolate p q = 146 | let rec p' = equalitize p 147 | and q' = equalitize q 148 | let rec p'' = if p' = p then p else And (fst (dest_imp p'), p) 149 | and q'' = if q' = q then q else And (fst (dest_imp q'), q) 150 | interpolate p'' q'' 151 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/intro.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.intro 8 | 9 | open System 10 | 11 | // pg.14 12 | // ========================================================================= // 13 | // Simple algebraic expression example from the introductory chapter. // 14 | // ========================================================================= // 15 | 16 | type expression = 17 | | Var of string 18 | | Const of int 19 | | Add of expression * expression 20 | | Mul of expression * expression 21 | 22 | // pg. 15 23 | // ------------------------------------------------------------------------- // 24 | // Simplification example. // 25 | // ------------------------------------------------------------------------- // 26 | 27 | let simplify1 expr = 28 | match expr with 29 | | Mul (Const 0, x) 30 | | Mul (x, Const 0) -> 31 | Const 0 32 | | Add (Const 0, x) 33 | | Add (x, Const 0) 34 | | Mul (Const 1, x) 35 | | Mul (x, Const 1) -> 36 | x 37 | | Add (Const m, Const n) -> 38 | Const (m + n) 39 | | Mul (Const m, Const n) -> 40 | Const (m * n) 41 | | _ -> expr 42 | 43 | let rec simplify expr = 44 | match expr with 45 | | Add (e1, e2) -> 46 | Add (simplify e1, simplify e2) 47 | |> simplify1 48 | | Mul (e1, e2) -> 49 | Mul (simplify e1, simplify e2) 50 | |> simplify1 51 | | _ -> 52 | simplify1 expr 53 | 54 | // pg. 17 55 | // ------------------------------------------------------------------------- // 56 | // Lexical analysis. // 57 | // ------------------------------------------------------------------------- // 58 | 59 | let matches s = 60 | let chars = 61 | explode s 62 | fun c -> mem c chars 63 | 64 | let space = matches " \t\n\r" 65 | 66 | let punctuation = matches "()[]{}," 67 | 68 | let symbolic = matches "~`!@#$%^&*-+=|\\:;<>.?/" 69 | 70 | let numeric = matches "0123456789" 71 | 72 | let alphanumeric = matches "abcdefghijklmnopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" 73 | 74 | let rec lexwhile prop inp = 75 | match inp with 76 | | c :: cs when prop c -> 77 | let tok, rest = lexwhile prop cs 78 | c + tok, rest 79 | | _ -> "", inp 80 | 81 | let rec lex inp = 82 | match snd <| lexwhile space inp with 83 | | [] -> [] 84 | | c :: cs -> 85 | let prop = 86 | if alphanumeric c then alphanumeric 87 | else if symbolic c then symbolic 88 | else fun c -> false 89 | let toktl, rest = lexwhile prop cs 90 | (c + toktl) :: lex rest 91 | 92 | // pg. 19 93 | // ------------------------------------------------------------------------- // 94 | // Parsing. // 95 | // ------------------------------------------------------------------------- // 96 | 97 | let rec parse_expression i = 98 | match parse_product i with 99 | | e1, "+" :: i1 -> 100 | let e2, i2 = parse_expression i1 101 | Add (e1, e2), i2 102 | | x -> x 103 | 104 | and parse_product i = 105 | match parse_atom i with 106 | | e1, "*" :: i1 -> 107 | let e2, i2 = parse_product i1 108 | Mul (e1, e2), i2 109 | | x -> x 110 | 111 | and parse_atom i = 112 | match i with 113 | | [] -> 114 | failwith "Expected an expression at end of input" 115 | | "(" :: i1 -> 116 | match parse_expression i1 with 117 | | e2, ")" :: i2 -> e2, i2 118 | | _ -> failwith "Expected closing bracket" 119 | | tok :: i1 -> 120 | if List.forall numeric (explode tok) then 121 | Const (int tok), i1 122 | else Var tok, i1 123 | 124 | // pg. 20 125 | // ------------------------------------------------------------------------- // 126 | // Generic function to impose lexing and exhaustion checking on a parser. // 127 | // ------------------------------------------------------------------------- // 128 | 129 | let make_parser pfn (s : string) = 130 | let tokens = 131 | // Replace newlines with spaces so the lexer and parser 132 | // work correctly on multi-line strings. 133 | // TODO : This could probably be optimized to make the replacements 134 | // in a single pass using a Regex. 135 | s.Replace('\r', ' ') 136 | .Replace('\n', ' ') 137 | // Reduce multiple spaces to single spaces to help the parser. 138 | .Replace(" ", " ") 139 | |> explode 140 | |> lex 141 | 142 | match pfn tokens with 143 | | expr, [] -> 144 | expr 145 | | _, rest -> 146 | failwithf "Unparsed input: %i tokens remaining in buffer." 147 | <| List.length rest 148 | 149 | let parse_exp = 150 | make_parser parse_expression 151 | 152 | // pg. 21 153 | // ------------------------------------------------------------------------- // 154 | // Conservatively bracketing first attempt at printer. // 155 | // ------------------------------------------------------------------------- // 156 | 157 | let rec string_of_exp e = 158 | match e with 159 | | Var s -> s 160 | | Const n -> string n 161 | | Add (e1, e2) -> 162 | "(" + (string_of_exp e1) + " + " + (string_of_exp e2) + ")" 163 | | Mul (e1, e2) -> 164 | "(" + (string_of_exp e1) + " * " + (string_of_exp e2) + ")" 165 | 166 | // pg. 22 167 | // ------------------------------------------------------------------------- // 168 | // Somewhat better attempt. // 169 | // ------------------------------------------------------------------------- // 170 | 171 | let rec string_of_exp_2 pr e = 172 | match e with 173 | | Var s -> s 174 | | Const n -> string n 175 | | Add (e1, e2) -> 176 | let s = (string_of_exp_2 3 e1) + " + " + (string_of_exp_2 2 e2) 177 | if 2 < pr then "(" + s + ")" 178 | else s 179 | | Mul (e1, e2) -> 180 | let s = (string_of_exp_2 5 e1) + " * " + (string_of_exp_2 4 e2) 181 | if 4 < pr then "(" + s + ")" 182 | else s 183 | 184 | let print_exp e = 185 | printfn "%O" ("<<" + string_of_exp_2 0 e + ">>") 186 | 187 | let sprint_exp e = 188 | "<<" + string_of_exp_2 0 e + ">>" -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/meson.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.meson 8 | 9 | open formulas 10 | open prop 11 | open fol 12 | open skolem 13 | open tableaux 14 | open prolog 15 | 16 | // ========================================================================= // 17 | // Model elimination procedure (MESON version, based on Stickel's PTTP). // 18 | // ========================================================================= // 19 | 20 | // pg. 219 21 | // ------------------------------------------------------------------------- // 22 | // Generation of contrapositives. // 23 | // ------------------------------------------------------------------------- // 24 | 25 | let contrapositives cls = 26 | let baseClause = List.map (fun c -> List.map negate (subtract cls [c]), c) cls 27 | if List.forall negative cls then 28 | (List.map negate cls, False) :: baseClause 29 | else baseClause 30 | 31 | // pg. 220 32 | // ------------------------------------------------------------------------- // 33 | // The core of MESON: ancestor unification or Prolog-style extension. // 34 | // ------------------------------------------------------------------------- // 35 | 36 | let rec mexpand001 rules ancestors g cont (env, n, k) = 37 | if n < 0 then failwith "Too deep" 38 | else 39 | let rec tryfind f l = 40 | match l with 41 | | [] -> failwith "tryfind" 42 | | h :: t -> 43 | try f h 44 | with _ -> 45 | tryfind f t 46 | try 47 | tryfind (fun a -> cont (unify_literals env (g, negate a), n, k)) ancestors 48 | with _ -> 49 | tryfind (fun rule -> 50 | let (asm, c) ,k' = renamerule k rule 51 | List.foldBack (mexpand001 rules (g :: ancestors)) asm cont 52 | (unify_literals env (g, c), n - List.length asm, k')) 53 | rules 54 | 55 | // pg. 220 56 | // ------------------------------------------------------------------------- // 57 | // Full MESON procedure. // 58 | // ------------------------------------------------------------------------- // 59 | 60 | let puremeson001 fm = 61 | let cls = simpcnf (specialize (pnf fm)) 62 | let rules = List.foldBack ((@) << contrapositives) cls [] 63 | deepen (fun n -> 64 | mexpand001 rules [] False id (undefined, n, 0) 65 | |> ignore 66 | n) 0 67 | 68 | let meson001 fm = 69 | let fm1 = askolemize (Not (generalize fm)) 70 | List.map (puremeson001 << list_conj) (simpdnf fm1) 71 | 72 | // pg. 221 73 | // ------------------------------------------------------------------------- // 74 | // With repetition checking and divide-and-conquer search. // 75 | // ------------------------------------------------------------------------- // 76 | 77 | let rec equal env fm1 fm2 = 78 | try unify_literals env (fm1, fm2) = env 79 | with _ -> false 80 | 81 | let expand2 expfn goals1 n1 goals2 n2 n3 cont env k = 82 | expfn goals1 (fun (e1, r1, k1) -> 83 | expfn goals2 (fun (e2, r2, k2) -> 84 | if n2 + r1 <= n3 + r2 then failwith "pair" 85 | else cont(e2, r2, k2)) 86 | (e1, n2 + r1, k1)) 87 | (env, n1, k) 88 | 89 | let rec mexpand002 rules ancestors g cont (env, n, k) = 90 | 91 | let rec mexpands002 rules ancestors gs cont (env, n, k) = 92 | if n < 0 then failwith "Too deep" 93 | else 94 | let m = List.length gs 95 | if m <= 1 then List.foldBack (mexpand002 rules ancestors) gs cont (env, n, k) 96 | else 97 | let n1 = n / 2 98 | let n2 = n - n1 99 | let goals1,goals2 = chop_list (m / 2) gs 100 | let expfn = expand2 (mexpands002 rules ancestors) 101 | try expfn goals1 n1 goals2 n2 -1 cont env k 102 | with _ -> expfn goals2 n1 goals1 n2 n1 cont env k 103 | 104 | if n < 0 then 105 | failwith "Too deep" 106 | elif List.exists (equal env g) ancestors then 107 | failwith "repetition" 108 | else 109 | let rec tryfind f l = 110 | match l with 111 | | [] -> failwith "tryfind" 112 | | h :: t -> 113 | try f h 114 | with _ -> tryfind f t 115 | try tryfind (fun a -> cont (unify_literals env (g, negate a), n, k)) ancestors with 116 | | Failure _ -> 117 | tryfind (fun r -> 118 | let (asm, c), k' = renamerule k r 119 | mexpands002 rules (g :: ancestors) asm cont (unify_literals env (g, c), n - List.length asm, k')) 120 | rules 121 | 122 | let puremeson002 fm = 123 | let cls = simpcnf (specialize (pnf fm)) 124 | let rules = List.foldBack ((@) << contrapositives) cls [] 125 | deepen (fun n -> 126 | mexpand002 rules [] False id (undefined, n, 0) 127 | |> ignore 128 | n) 0 129 | 130 | let meson002 fm = 131 | let fm1 = askolemize (Not (generalize fm)) 132 | List.map (puremeson002 << list_conj) (simpdnf fm1) 133 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/order.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.order 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open defcnf 13 | open dp 14 | open stal 15 | open bdd 16 | open fol 17 | open skolem 18 | open herbrand 19 | open unif 20 | open tableaux 21 | open resolution 22 | open prolog 23 | open meson 24 | open skolems 25 | open equal 26 | open cong 27 | open rewrite 28 | 29 | // pg. 265 30 | // ========================================================================= // 31 | // Term orderings. // 32 | // ========================================================================= // 33 | 34 | let rec termsize tm = 35 | match tm with 36 | | Var x -> 1 37 | | Fn (f, args) -> 38 | List.foldBack (fun t n -> termsize t + n) args 1 39 | 40 | // pg. 267 41 | // ------------------------------------------------------------------------- // 42 | // Lexicographic path order. // 43 | // ------------------------------------------------------------------------- // 44 | 45 | let rec lexord ord l1 l2 = 46 | match l1, l2 with 47 | | h1 :: t1, h2 :: t2 -> 48 | if ord h1 h2 then 49 | List.length t1 = List.length t2 50 | else h1 = h2 && lexord ord t1 t2 51 | | _ -> false 52 | 53 | let rec lpo_gt w s t = 54 | match s, t with 55 | | _, Var x -> 56 | not (s = t) 57 | && mem x (fvt s) 58 | | Fn (f, fargs), Fn (g, gargs) -> 59 | List.exists (fun si -> lpo_ge w si t) fargs 60 | || List.forall (lpo_gt w s) gargs 61 | && (f = g 62 | && lexord (lpo_gt w) fargs gargs 63 | || w (f, List.length fargs) (g ,List.length gargs)) 64 | | _ -> false 65 | 66 | and lpo_ge w s t = 67 | (s = t) || lpo_gt w s t 68 | 69 | // pg. 267 70 | // ------------------------------------------------------------------------- // 71 | // More convenient way of specifying weightings. // 72 | // ------------------------------------------------------------------------- // 73 | 74 | let weight lis (f, n) (g, m) = 75 | if f = g then 76 | n > m 77 | else 78 | earlier lis g f 79 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/paramodulation.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.paramodulation 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open defcnf 13 | open dp 14 | open stal 15 | open bdd 16 | open fol 17 | open skolem 18 | open herbrand 19 | open unif 20 | open tableaux 21 | open resolution 22 | open prolog 23 | open meson 24 | open skolems 25 | open equal 26 | open cong 27 | open rewrite 28 | open order 29 | open completion 30 | open eqelim 31 | 32 | // ========================================================================= // 33 | // Paramodulation. // 34 | // ========================================================================= // 35 | 36 | // pg. 301 37 | // ------------------------------------------------------------------------- // 38 | // Find paramodulations with l = r inside a literal fm. // 39 | // ------------------------------------------------------------------------- // 40 | 41 | let rec overlapl (l, r) fm rfn = 42 | match fm with 43 | | Atom (R (f, args)) -> 44 | listcases (overlaps (l, r)) (fun i a -> rfn i (Atom (R (f, a)))) args [] 45 | | Not p -> 46 | overlapl (l, r) p (fun i p -> rfn i (Not p)) 47 | | _ -> failwith "overlapl: not a literal" 48 | 49 | // pg. 301 50 | // ------------------------------------------------------------------------- // 51 | // Now find paramodulations within a clause. // 52 | // ------------------------------------------------------------------------- // 53 | 54 | let overlapc (l, r) cl rfn acc = 55 | listcases (overlapl (l, r)) rfn cl acc 56 | 57 | // pg. 301 58 | // ------------------------------------------------------------------------- // 59 | // Overall paramodulation of ocl by equations in pcl. // 60 | // ------------------------------------------------------------------------- // 61 | 62 | let paramodulate pcl ocl = 63 | List.foldBack (fun eq -> 64 | let pcl' = subtract pcl [eq] 65 | let l, r = dest_eq eq 66 | let rfn i ocl' = image (subst i) (pcl' @ ocl') 67 | overlapc (l, r) ocl rfn << overlapc (r, l) ocl rfn) 68 | (List.filter is_eq pcl) [] 69 | 70 | let para_clauses cls1 cls2 = 71 | let cls1' = rename "x" cls1 72 | let cls2' = rename "y" cls2 73 | paramodulate cls1' cls2' @ paramodulate cls2' cls1' 74 | 75 | // pg. 302 76 | // ------------------------------------------------------------------------- // 77 | // Incorporation into resolution loop. // 78 | // ------------------------------------------------------------------------- // 79 | 80 | let rec paraloop (used, unused) = 81 | match unused with 82 | | cls :: ros -> 83 | printfn "%i used; %i unused." (List.length used) (List.length unused) 84 | let used' = insert cls used 85 | let news = 86 | List.foldBack (@) (mapfilter (resolve_clauses cls) used') 87 | (List.foldBack (@) (mapfilter (para_clauses cls) used') []) 88 | if mem [] news then true 89 | else 90 | paraloop (used', List.foldBack (incorporate cls) news ros) 91 | 92 | let pure_paramodulation fm = 93 | paraloop ([], [mk_eq (Var "x") (Var "x")] :: simpcnf (specialize (pnf fm))) 94 | 95 | let paramodulation fm = 96 | let fm1 = askolemize (Not (generalize fm)) 97 | List.map (pure_paramodulation << list_conj) (simpdnf fm1) 98 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/prolog.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.prolog 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open fol 13 | open skolem 14 | open unif 15 | open tableaux 16 | 17 | // ========================================================================= // 18 | // Backchaining procedure for Horn clauses, and toy Prolog implementation. // 19 | // ========================================================================= // 20 | 21 | // pg. 207 22 | // ------------------------------------------------------------------------- // 23 | // Rename a rule. // 24 | // ------------------------------------------------------------------------- // 25 | 26 | let renamerule k (asm, c) = 27 | let fvs = fv (list_conj (c :: asm)) 28 | let n = List.length fvs 29 | let vvs = List.map (fun i -> "_" + string i) (k -- (k + n - 1)) 30 | let inst = subst (fpf fvs (List.map (fun x -> Var x) vvs)) 31 | (List.map inst asm, inst c), k + n 32 | 33 | // pg. 207 34 | // ------------------------------------------------------------------------- // 35 | // Basic prover for Horn clauses based on backchaining with unification. // 36 | // ------------------------------------------------------------------------- // 37 | 38 | let rec backchain rules n k env goals = 39 | match goals with 40 | | [] -> env 41 | | g :: gs -> 42 | if n = 0 then failwith "Too deep" 43 | else 44 | let rec tryfind f l = 45 | match l with 46 | | [] -> failwith "tryfind" 47 | | h :: t -> 48 | try f h 49 | with _ -> tryfind f t 50 | tryfind ( 51 | fun rule -> 52 | let (a, c), k' = 53 | renamerule k rule 54 | backchain rules (n - 1) k' (unify_literals env (c, g)) (a @ gs)) 55 | rules 56 | 57 | let hornify cls = 58 | let pos, neg = List.partition positive cls 59 | if List.length pos > 1 then 60 | failwith "non-Horn clause" 61 | else 62 | List.map negate neg, (if pos = [] then False else List.head pos) 63 | 64 | let hornprove fm = 65 | let rules = List.map hornify (simpcnf (skolemize (Not (generalize fm)))) 66 | deepen (fun n -> backchain rules n 0 undefined [False], n) 0 67 | 68 | // pg. 210 69 | // ------------------------------------------------------------------------- // 70 | // Parsing rules in a Prolog-like syntax. // 71 | // ------------------------------------------------------------------------- // 72 | 73 | let parserule s = 74 | let c, rest = 75 | parse_formula (parse_infix_atom, parse_atom) [] (lex (explode s)) 76 | let asm, rest1 = 77 | if rest <> [] && List.head rest = ":-" 78 | then parse_list "," 79 | (parse_formula (parse_infix_atom, parse_atom) []) (List.tail rest) 80 | else [], rest 81 | if rest1 = [] then asm, c 82 | else failwith "Extra material after rule" 83 | 84 | // pg. 210 85 | // ------------------------------------------------------------------------- // 86 | // Prolog interpreter: just use depth-first search not iterative deepening. // 87 | // ------------------------------------------------------------------------- // 88 | 89 | let simpleprolog rules gl = 90 | backchain (List.map parserule rules) -1 0 undefined [parse gl] 91 | 92 | // ------------------------------------------------------------------------- // 93 | // With instantiation collection to produce a more readable result. // 94 | // ------------------------------------------------------------------------- // 95 | 96 | let prolog rules gl = 97 | let i = solve (simpleprolog rules gl) 98 | mapfilter (fun x -> Atom (R ("=", [Var x; apply i x]))) (fv (parse gl)) 99 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/qelim.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.qelim 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open defcnf 13 | open dp 14 | open stal 15 | open bdd 16 | open fol 17 | open skolem 18 | open herbrand 19 | open unif 20 | open tableaux 21 | open resolution 22 | open prolog 23 | open meson 24 | open skolems 25 | open equal 26 | open cong 27 | open rewrite 28 | open order 29 | open completion 30 | open eqelim 31 | open paramodulation 32 | open decidable 33 | 34 | // ========================================================================= // 35 | // Introduction to quantifier elimination. // 36 | // ========================================================================= // 37 | 38 | // pg. 331 39 | // ------------------------------------------------------------------------- // 40 | // Lift procedure given literal modifier, formula normalizer, and a basic // 41 | // elimination procedure for existential formulas with conjunctive body. // 42 | // ------------------------------------------------------------------------- // 43 | 44 | let qelim bfn x p = 45 | let cjs = conjuncts p 46 | let ycjs, ncjs = List.partition (mem x << fv) cjs 47 | if ycjs = [] then p 48 | else 49 | let q = bfn (Exists (x, list_conj ycjs)) 50 | List.foldBack mk_and ncjs q 51 | 52 | let lift_qelim afn nfn qfn = 53 | let rec qelift vars fm = 54 | match fm with 55 | | Atom (R (_,_)) -> 56 | afn vars fm 57 | | Not p -> 58 | Not (qelift vars p) 59 | | And (p, q) -> 60 | And (qelift vars p, qelift vars q) 61 | | Or (p, q) -> 62 | Or (qelift vars p, qelift vars q) 63 | | Imp (p, q) -> 64 | Imp (qelift vars p, qelift vars q) 65 | | Iff (p, q) -> 66 | Iff (qelift vars p, qelift vars q) 67 | | Forall (x, p) -> 68 | Not (qelift vars (Exists (x, Not p))) 69 | | Exists (x, p) -> 70 | let djs = disjuncts (nfn (qelift (x :: vars) p)) 71 | list_disj (List.map (qelim (qfn vars) x) djs) 72 | | _ -> fm 73 | 74 | fun fm -> 75 | simplify (qelift (fv fm) (miniscope fm)) 76 | 77 | // pg. 333 78 | // ------------------------------------------------------------------------- // 79 | // Cleverer (proposisional) NNF with conditional and literal modification. // 80 | // ------------------------------------------------------------------------- // 81 | 82 | let cnnf lfn = 83 | let rec cnnf fm = 84 | match fm with 85 | | And (p, q) -> 86 | And (cnnf p, cnnf q) 87 | | Or (p, q) -> 88 | Or (cnnf p, cnnf q) 89 | | Imp (p, q) -> 90 | Or (cnnf(Not p), cnnf q) 91 | | Iff (p, q) -> 92 | Or (And (cnnf p, cnnf q), And (cnnf (Not p), cnnf (Not q))) 93 | | Not (Not p) -> 94 | cnnf p 95 | | Not (And (p, q)) -> 96 | Or (cnnf (Not p), cnnf (Not q)) 97 | | Not (Or (And (p, q), And (p', r))) when p' = negate p -> 98 | Or (cnnf (And (p, Not q)), cnnf (And (p', Not r))) 99 | | Not (Or (p, q)) -> 100 | And (cnnf (Not p), cnnf (Not q)) 101 | | Not (Imp (p, q)) -> 102 | And (cnnf p, cnnf (Not q)) 103 | | Not (Iff (p, q)) -> 104 | Or (And (cnnf p, cnnf (Not q)), And (cnnf (Not p), cnnf q)) 105 | | _ -> lfn fm 106 | simplify << cnnf << simplify 107 | 108 | // pg. 334 109 | // ------------------------------------------------------------------------- // 110 | // Initial literal simplifier and intermediate literal modifier. // 111 | // ------------------------------------------------------------------------- // 112 | 113 | let lfn_dlo fm = 114 | match fm with 115 | | Not (Atom (R ("<", [s; t]))) -> 116 | Or (Atom (R ("=", [s; t])), Atom (R ("<", [t; s]))) 117 | | Not (Atom (R ("=", [s; t]))) -> 118 | Or (Atom (R ("<", [s; t])), Atom (R ("<", [t; s]))) 119 | | _ -> fm 120 | 121 | // pg. 335 122 | // ------------------------------------------------------------------------- // 123 | // Simple example of dense linear orderings; this is the base function. // 124 | // ------------------------------------------------------------------------- // 125 | 126 | // Note: List.find throws expcetion it does not return failure 127 | // so "try with failure" will not work with List.find 128 | let dlobasic fm = 129 | match fm with 130 | | Exists (x, p) -> 131 | let cjs = subtract (conjuncts p) [Atom (R ("=", [Var x; Var x]))] 132 | try 133 | let eqn = List.find is_eq cjs 134 | let s, t = dest_eq eqn 135 | let y = if s = Var x then t else s 136 | list_conj (List.map (subst (x |=> y)) (subtract cjs [eqn])) 137 | with 138 | | Failure _ -> 139 | //| :? System.Collections.Generic.KeyNotFoundException -> // List.find is modified to return failure again 140 | if mem (Atom (R ("<", [Var x; Var x]))) cjs then False 141 | else 142 | let lefts, rights = List.partition (fun (Atom (R ("<", [s; t]))) -> t = Var x) cjs 143 | let ls = List.map (fun (Atom (R ("<", [l;_]))) -> l) lefts 144 | let rs = List.map (fun (Atom (R ("<", [_;r]))) -> r) rights 145 | list_conj (allpairs (fun l r -> Atom (R ("<", [l; r]))) ls rs) 146 | | _ -> failwith "dlobasic" 147 | 148 | // pg. 335 149 | // ------------------------------------------------------------------------- // 150 | // Overall quelim procedure. // 151 | // ------------------------------------------------------------------------- // 152 | 153 | let afn_dlo vars fm = 154 | match fm with 155 | | Atom (R ("<=", [s; t])) -> 156 | Not (Atom (R ("<", [t; s]))) 157 | | Atom (R (">=", [s; t])) -> 158 | Not (Atom (R ("<", [s; t]))) 159 | | Atom (R (">", [s; t])) -> 160 | Atom (R ("<", [t; s])) 161 | | _ -> fm 162 | 163 | let quelim_dlo = 164 | lift_qelim afn_dlo (dnf << cnnf lfn_dlo) (fun v -> dlobasic) 165 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/rewrite.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.rewrite 8 | 9 | open formulas 10 | open fol 11 | open resolution 12 | 13 | // 14 | // ========================================================================= // 15 | // Rewriting. // 16 | // ========================================================================= // 17 | 18 | // pg. 262 19 | // ------------------------------------------------------------------------- // 20 | // Rewriting at the top level with first of list of equations. // 21 | // ------------------------------------------------------------------------- // 22 | 23 | let rec rewrite1 eqs t = 24 | match eqs with 25 | | Atom (R ("=", [l; r])) :: oeqs -> 26 | try 27 | tsubst (term_match undefined [l, t]) r 28 | with _ -> 29 | rewrite1 oeqs t 30 | | _ -> failwith "rewrite1" 31 | 32 | // pg. 263 33 | // ------------------------------------------------------------------------- // 34 | // Rewriting repeatedly and at depth (top-down). // 35 | // ------------------------------------------------------------------------- // 36 | 37 | let rec rewrite eqs tm = 38 | try rewrite eqs (rewrite1 eqs tm) 39 | with _ -> 40 | match tm with 41 | | Var x -> tm 42 | | Fn (f, args) -> 43 | let tm' = Fn (f, List.map (rewrite eqs) args) 44 | if tm' = tm then tm 45 | else rewrite eqs tm' 46 | 47 | // ------------------------------------------------------------------------- // 48 | // Note that ML doesn't accept nonlinear patterns. // 49 | // ------------------------------------------------------------------------- // 50 | // 51 | // ********** Point being that CAML doesn't accept nonlinear patterns 52 | // 53 | //function (x,x) -> 0 54 | // 55 | // *********** Actually fun x x -> 0 works, but the xs seem to be 56 | // *********** considered distinct 57 | 58 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/skolems.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.skolems 8 | 9 | open fol 10 | open skolem 11 | 12 | // ========================================================================= // 13 | // Illustration of Skolemizing a set of formulas // 14 | // ========================================================================= // 15 | 16 | let rec rename_term tm = 17 | match tm with 18 | | Fn (f, args) -> 19 | Fn ("old_" + f, List.map rename_term args) 20 | | _ -> tm 21 | 22 | let rename_form = onformula rename_term 23 | 24 | let rec skolems fms corr = 25 | match fms with 26 | | [] -> 27 | [], corr 28 | | p :: ofms -> 29 | let p', corr' = skolem (rename_form p) corr 30 | let ps', corr'' = skolems ofms corr' 31 | p' :: ps', corr'' 32 | 33 | let skolemizes fms = 34 | fst <| skolems fms [] 35 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/tableaux.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.tableaux 8 | 9 | open intro 10 | open formulas 11 | open prop 12 | open fol 13 | open skolem 14 | open herbrand 15 | open unif 16 | 17 | // ========================================================================= // 18 | // Tableaux, seen as an optimized version of a Prawitz-like procedure. // 19 | // ========================================================================= // 20 | // 21 | // pg. 174 22 | // ------------------------------------------------------------------------- // 23 | // Unify literals (just pretend the toplevel relation is a function). // 24 | // ------------------------------------------------------------------------- // 25 | 26 | let rec unify_literals env tmp = 27 | match tmp with 28 | | Atom (R (p1, a1)), Atom (R (p2, a2)) -> 29 | unify env [Fn (p1, a1), Fn (p2, a2)] 30 | | Not p, Not q -> 31 | unify_literals env (p, q) 32 | | False, False -> env 33 | | _ -> failwith "Can't unify literals" 34 | 35 | // pg. 174 36 | // ------------------------------------------------------------------------- // 37 | // Unify complementary literals. // 38 | // ------------------------------------------------------------------------- // 39 | 40 | let unify_complements env (p, q) = 41 | unify_literals env (p, negate q) 42 | 43 | // pg. 174 44 | // ------------------------------------------------------------------------- // 45 | // Unify and refute a set of disjuncts. // 46 | // ------------------------------------------------------------------------- // 47 | 48 | // Note: Used book tryfind instead of F# List.tryFind 49 | let rec unify_refute djs (acc : func) : func = 50 | let rec tryfind f l = 51 | match l with 52 | | [] -> 53 | failwith "tryfind" 54 | | h::t -> 55 | try f h 56 | with _ -> 57 | tryfind f t 58 | 59 | match djs with 60 | | [] -> acc 61 | | head :: tail -> 62 | let pos, neg = List.partition positive head 63 | let unifyResult = unify_complements acc 64 | tryfind (unify_refute tail << unify_complements acc) (allpairs (fun p q -> (p, q)) pos neg) 65 | 66 | 67 | // pg. 175 68 | // ------------------------------------------------------------------------- // 69 | // Hence a Prawitz-like procedure (using unification on DNF). // 70 | // ------------------------------------------------------------------------- // 71 | 72 | let rec prawitz_loop djs0 fvs djs n = 73 | let l = List.length fvs 74 | let newvars = List.map (fun k -> "_" + string (n * l + k)) (1--l) 75 | let inst = fpf fvs (List.map (fun x -> Var x) newvars) 76 | let djs1 = distrib (image (image (subst inst)) djs0) djs 77 | try unify_refute djs1 undefined,(n + 1) with 78 | | Failure _ -> prawitz_loop djs0 fvs djs1 (n + 1) 79 | 80 | let prawitz fm = 81 | let fm0 = skolemize (Not (generalize fm)) 82 | snd <| prawitz_loop (simpdnf fm0) (fv fm0) [[]] 0 83 | 84 | // ------------------------------------------------------------------------- // 85 | // Comparison of number of ground instances. // 86 | // ------------------------------------------------------------------------- // 87 | 88 | let compare fm = 89 | prawitz fm, davisputnam fm 90 | 91 | // pg. 177 92 | // ------------------------------------------------------------------------- // 93 | // More standard tableau procedure, effectively doing DNF incrementally. // 94 | // ------------------------------------------------------------------------- // 95 | 96 | let rec tableau (fms, lits, n) cont (env, k) = 97 | if n < 0 then failwith "no proof at this level" 98 | else 99 | match fms with 100 | | [] -> failwith "tableau: no proof" 101 | | And (p, q) :: unexp -> 102 | tableau (p :: q :: unexp, lits, n) cont (env, k) 103 | | Or (p, q) :: unexp -> 104 | tableau (p :: unexp, lits, n) (tableau (q :: unexp, lits, n) cont) (env, k) 105 | | Forall (x, p) :: unexp -> 106 | let y = Var ("_" + string k) 107 | let p' = subst (x |=> y) p 108 | tableau (p' :: unexp @ [Forall (x, p)], lits, n - 1) cont (env, k + 1) 109 | | fm :: unexp -> 110 | let rec tryfind f l = 111 | match l with 112 | | [] -> failwith "tryfind" 113 | | h :: t -> 114 | try f h 115 | with _ -> 116 | tryfind f t 117 | try 118 | lits 119 | |> tryfind (fun l -> 120 | cont (unify_complements env (fm, l), k)) 121 | with _ -> 122 | tableau (unexp, fm :: lits, n) cont (env, k) 123 | 124 | let rec deepen f n = 125 | try printf "Searching with depth limit " 126 | printfn "%d" n 127 | f n 128 | with _ -> 129 | deepen f (n + 1) 130 | 131 | let tabrefute fms = 132 | deepen (fun n -> 133 | tableau (fms, [], n) id (undefined, 0) 134 | |> ignore 135 | n) 0 136 | 137 | let tab fm = 138 | let sfm = askolemize (Not (generalize fm)) 139 | if sfm = False then 0 else tabrefute [sfm] 140 | 141 | // pg. 178 142 | // ------------------------------------------------------------------------- // 143 | // Try to split up the initial formula first; often a big improvement. // 144 | // ------------------------------------------------------------------------- // 145 | 146 | let splittab fm = 147 | generalize fm 148 | |> Not 149 | |> askolemize 150 | |> simpdnf 151 | |> List.map tabrefute 152 | 153 | -------------------------------------------------------------------------------- /FSharpx.Books.AutomatedReasoning/unif.fs: -------------------------------------------------------------------------------- 1 | // ========================================================================= // 2 | // Copyright (c) 2003-2007, John Harrison. // 3 | // Copyright (c) 2012 Eric Taucher, Jack Pappas, Anh-Dung Phan // 4 | // (See "LICENSE.txt" for details.) // 5 | // ========================================================================= // 6 | 7 | module FSharpx.Books.AutomatedReasoning.unif 8 | 9 | open intro 10 | open fol 11 | 12 | // pg. 167 13 | // ========================================================================= // 14 | // Unification for first order terms. // 15 | // ========================================================================= // 16 | 17 | let rec istriv env x t = 18 | match t with 19 | | Var y -> 20 | y = x 21 | || defined env y 22 | && istriv env x (apply env y) 23 | | Fn(f,args) -> 24 | List.exists (istriv env x) args 25 | && failwith "cyclic" 26 | 27 | // ------------------------------------------------------------------------- // 28 | // Main unification procedure // 29 | // ------------------------------------------------------------------------- // 30 | 31 | let rec unify (env : func) eqs = 32 | match eqs with 33 | | [] -> env 34 | | (Fn (f, fargs), Fn (g, gargs)) :: oth -> 35 | if f = g && List.length fargs = List.length gargs then 36 | unify env (List.zip fargs gargs @ oth) 37 | else 38 | failwith "impossible unification" 39 | | (Var x, t) :: oth 40 | | (t, Var x) :: oth -> 41 | if defined env x then 42 | unify env ((apply env x,t) :: oth) 43 | else 44 | unify (if istriv env x t then env else (x |-> t) env) oth 45 | 46 | // pg. 169 47 | // ------------------------------------------------------------------------- // 48 | // Solve to obtain a single instantiation. // 49 | // ------------------------------------------------------------------------- // 50 | 51 | let rec solve env = 52 | let env' = mapf (tsubst env) env 53 | if env' = env then env 54 | else solve env' 55 | 56 | // pg. 171 57 | // ------------------------------------------------------------------------- // 58 | // Unification reaching a final solved form (often this isn't needed). // 59 | // ------------------------------------------------------------------------- // 60 | 61 | let fullunify eqs = solve (unify undefined eqs) 62 | 63 | // pg. 171 64 | // ------------------------------------------------------------------------- // 65 | // Examples. // 66 | // ------------------------------------------------------------------------- // 67 | 68 | let unify_and_apply eqs = 69 | let i = fullunify eqs 70 | let apply (t1, t2) = 71 | tsubst i t1, tsubst i t2 72 | List.map apply eqs 73 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 2 | By downloading, copying, installing or using the software you agree 3 | to this license. If you do not agree to this license, do not 4 | download, install, copy or use the software. 5 | 6 | Copyright (c) 2003-2007, John Harrison 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions 11 | are met: 12 | 13 | * Redistributions of source code must retain the above copyright 14 | notice, this list of conditions and the following disclaimer. 15 | 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | 20 | * The name of John Harrison may not be used to endorse or promote 21 | products derived from this software without specific prior written 22 | permission. 23 | 24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 31 | USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 34 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 | SUCH DAMAGE. 36 | 37 | =================================================================== 38 | 39 | Converted to F# 2.0 40 | 41 | Copyright (c) 2012, Eric Taucher, Jack Pappas, Anh-Dung Phan 42 | All rights reserved. 43 | 44 | Redistribution and use in source and binary forms, with or without 45 | modification, are permitted provided that the following conditions 46 | are met: 47 | 48 | * Redistributions of source code must retain the above copyright 49 | notice, this list of conditions and the previous disclaimer. 50 | 51 | * Redistributions in binary form must reproduce the above copyright 52 | notice, this list of conditions and the previous disclaimer in the 53 | documentation and/or other materials provided with the distribution. 54 | 55 | * The name of Eric Taucher, Jack Pappas, or Anh-Dung Phan may not be 56 | used to endorse or promote products derived from this software without 57 | specific prior written permission of each person. 58 | 59 | -------------------------------------------------------------------------------- /OCaml Results.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jack-pappas/fsharp-logic-examples/1e12807ed98301b94bb6b3aa61e1b06089eec269/OCaml Results.pdf -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | --------------------------------------------------------------------------------