The project aims to solve the famous SAT problem in a efficient way. In order to do that it’s used an original algorithm based on conservative retractions (dual notion of conservtive extension). Further information obout it could be found here?.
The documentation about the modules it’s hosted here.
This directory stores several examples of sets of formulas in DIMACS format. See DIMACS format for further information about it.
- Corresponds to the formula: (p ^ q)
- It’s True
- Corresponds to the formula: (p ^ q) v (¬p ^ q)
- It’s True
- Corresponds to the formula: (p ^ q) v (¬p ^ q) v (p ^ ¬q)
- It’s True
- Corresponds to the formula: (p ^ q) v (¬p ^ q) v (p ^ ¬q) v (¬p ^ ¬q)
- It’s False
*MainFunctions> satCNF "exDIMACS/medium/exampleSat0.txt" frequency
The satisfactibility of instance exDIMACS/medium/exampleSat0.txt is:
True
(0.15 secs, 16,183,888 bytes)
*MainFunctions> satCNF "exDIMACS/medium/exampleSat1.txt" frequency
The satisfactibility of instance exDIMACS/medium/exampleSat1.txt is:
True
(0.17 secs, 18,794,728 bytes)
*MainFunctions> satCNF "exDIMACS/medium/exampleSat2.txt" frequency
The satisfactibility of instance exDIMACS/medium/exampleSat2.txt is:
True
(0.33 secs, 38,287,824 bytes)
*MainFunctions> satCNF "exDIMACS/medium/exampleSat3.txt" frequency
The satisfactibility of instance exDIMACS/medium/exampleSat3.txt is:
- Has 430 clauses
- Has 100 variables
- It’s True
- Has 1065 clauses
- Has 250 variables
- It’s True
- Has 1065 clauses
- Has 250 variables
- It’s False
*MainFunctions> satCNF "exDIMACS/hard/unsat250.cnf" frequency
The satisfactibility of instance exDIMACS/hard/unsat250.cnf is:
False
(0.24 secs, 72,635,480 bytes)
https://github.com/andrepd/haskell-logic/blob/master/logic_parser.hs
Aquí se describen las pautas a seguir para poder usar la librería, suponiendo que el lector no tiene instalados ninguno de los programas necesarios.
En primer lugar será necesario git . En caso de no estar instalado siga las instrucciones del enlace anterior.
Una vez instalado git correctamente, vaya a la terminal de comandos y escriba:
git clone https://github.com/DanielRodCha/SAT-canonical.git
La librería está escrita en lenguaje Haskell, así que se será necesario instalar la herramienta stack. Dicha herramienta será muy útil ya que construirá todo el proyecto, además de descargar las librerías auxiliares.
Tras haber completado la instalación de la herramienta stack, navegue por los ficheros desde el terminal hasta encontrarse en la carpeta SAT-Pol, que se creó en el paso anterior. A continuación, construya el proyecto escribiendo en el terminal:
stack update stack build
Por último, se recomienda al usuario que cargue el módulo src/MainFunctions, ya que en él figuran las funciones más importantes de la librería. Para ello, escriba en la terminal:
:SAT-canonical danrodcha$ stack ghci Configuring GHCi with the following packages: SAT-canonical The main module to load is ambiguous. Candidates are: 1. Package `SAT-canonical' component exe:sat with main-is file: /Users/danrodcha/SAT-canonical/app2/Main.hs 2. Package `SAT-canonical' component exe:satCNF with main-is file: /Users/danrodcha/SAT-canonical/app/Main.hs You can specify which one to pick by: * Specifying targets to stack ghci e.g. stack ghci SAT-canonical:exe:sat * Specifying what the main is e.g. stack ghci --main-is SAT-canonical:exe:sat * Choosing from the candidate above [1..2] Specify main module to use (press enter to load none):
Pulse Enter:
Not loading any main modules, as no valid module selected GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help [1 of 8] Compiling Logic ( /Users/danrodcha/SAT-canonical/src/Logic.hs, interpreted ) [2 of 8] Compiling Heuristics ( /Users/danrodcha/SAT-canonical/src/Heuristics.hs, interpreted ) [3 of 8] Compiling LogicParser ( /Users/danrodcha/SAT-canonical/src/LogicParser.hs, interpreted ) [4 of 8] Compiling Simplification ( /Users/danrodcha/SAT-canonical/src/Simplification.hs, interpreted ) [5 of 8] Compiling Preprocessing ( /Users/danrodcha/SAT-canonical/src/Preprocessing.hs, interpreted ) [6 of 8] Compiling Canonical ( /Users/danrodcha/SAT-canonical/src/Canonical.hs, interpreted ) [7 of 8] Compiling Saturation ( /Users/danrodcha/SAT-canonical/src/Saturation.hs, interpreted ) [8 of 8] Compiling MainFunctions ( /Users/danrodcha/SAT-canonical/src/MainFunctions.hs, interpreted ) Ok, 8 modules loaded. Loaded GHCi configuration from /private/var/folders/k5/5wbfgm4d5cbbbgm0c9hqk94m0000gn/T/ghci5683/ghci-script *Simplification Canonical Heuristics Logic LogicParser MainFunctions Preprocessing Saturation Simplification>
Cargue el módulo MainFunctions:
*Simplification Canonical Heuristics Logic LogicParser MainFunctions Preprocessing Saturation Simplification> :l MainFunctions [1 of 8] Compiling Logic ( /Users/danrodcha/SAT-canonical/src/Logic.hs, interpreted ) [2 of 8] Compiling Heuristics ( /Users/danrodcha/SAT-canonical/src/Heuristics.hs, interpreted ) [3 of 8] Compiling LogicParser ( /Users/danrodcha/SAT-canonical/src/LogicParser.hs, interpreted ) [4 of 8] Compiling Simplification ( /Users/danrodcha/SAT-canonical/src/Simplification.hs, interpreted ) [5 of 8] Compiling Preprocessing ( /Users/danrodcha/SAT-canonical/src/Preprocessing.hs, interpreted ) [6 of 8] Compiling Canonical ( /Users/danrodcha/SAT-canonical/src/Canonical.hs, interpreted ) [7 of 8] Compiling Saturation ( /Users/danrodcha/SAT-canonical/src/Saturation.hs, interpreted ) [8 of 8] Compiling MainFunctions ( /Users/danrodcha/SAT-canonical/src/MainFunctions.hs, interpreted ) Ok, 8 modules loaded. *MainFunctions>
Como una base de conocimiento es un conjunto de reglas, las listas de reglas se sumergirán en el tipo de dato Set (conjunto). Esto nos permite trabajar con bases de conocimiento sin elementos repetidos, es decir sin redundancias. Para hacer esta inmersión manualmente se puede usar la función fromList:
*MainFunctions> S.fromList []
fromList []
*MainFunctions> S.fromList [1,2,3,1,2]
fromList [1,2,3]
A continuación se exponen las principales tareas que puede resolver esta librería:
Para ello basta con usar la función forgetVarKB:
*MainFunctions> f1 = Disj p q
*MainFunctions> f2 = Conj q p
*MainFunctions> forgetVarKB "p" (S.fromList[f1,f2])
fromList [⊤,q,(q & q)]
*MainFunctions> forgetVarKB "q" (S.fromList[f1,Neg f2])
fromList [⊤,(-p | p)]
Existen dos formas de hacerlo, dejando que la librería escoja el orden en el que va a olvidar cada variable (según una heurística) o especificándolo manualmente.
- Según heurística:
*MainFunctions> f1 = Conj p q
*MainFunctions> f2 = (Neg r)
*MainFunctions> f3 = Disj r (Neg q)
*MainFunctions> forgetVarListKB' (S.fromList [f1,f2,f3]) ["p","q","r"] frequency
[fromList [-r,(q & q),(r | -q)],fromList [⊤,r,-r],fromList [⊥]]
- Orden dado:
*MainFunctions> f1 = Conj p q
*MainFunctions> f2 = (Neg r)
*MainFunctions> f3 = Disj r (Neg q)
*MainFunctions> forgetVarListKB (S.fromList [f1,f2,f3]) ["p","q","r"]
[fromList [-r,(q & q),(r | -q)],fromList [⊤,r,-r],fromList [⊥]]
*MainFunctions> forgetVarListKB (S.fromList [f1,f2,f3]) ["r","q","p"]
[fromList [⊤,-q,(p & q)],fromList [⊥],fromList [⊥]]
Existen dos funciones para hacerlo, la primera resuelve directamente el problema y nos da la solución:
*MainFunctions> f1 = Conj p q
*MainFunctions> f2 = (Neg r)
*MainFunctions> f3 = Disj r (Neg q)
*MainFunctions> saturateKB (S.fromList [f1,f2,f3]) ["r","q","p"] frequency
False
Mientras que la segunda, devuelve la traza de los cálculos realizados:
*MainFunctions> f1 = Conj p q
*MainFunctions> f2 = (Neg r)
*MainFunctions> f3 = Disj r (Neg q)
*MainFunctions> saturateKBTrace (S.fromList [f1,f2,f3]) ["r","q","p"] frequency
[(fromList [-r,(p & q),(r | -q)],True),(fromList [⊤,-q,(p & q)],True),(fromList [⊤,-q,(q & q)],True),(fromList [⊥],False)]
Una de las ventajas de esta librería es que permite interactuar con ejemplos escritos en archivos de texto, aunque deben estar escritos en formatos aptos, es decir, formato DIMACS o la sintaxis de Prover9:
Si el archivo contiene la base de conocimiento en formato DIMACS, las funciones que sirven para interactuar son:
*MainFunctions> dimacs "exDIMACS/easy/example1.txt"
(fromList [⊤,(p2 | p1)],["p2","p1"])
*MainFunctions> satCNF "exDIMACS/easy/example1.txt" frequency
The satisfactibility of instance exDIMACS/easy/example1.txt is:
True
*MainFunctions> dimacs "exDIMACS/easy/example4.txt"
(fromList [⊤,(p2 | p1),(p2 | -p1),(-p2 | p1),(-p2 | -p1)],["p2","p1"])
*MainFunctions> satCNF "exDIMACS/easy/example4.txt" frequency
The satisfactibility of instance exDIMACS/easy/example4.txt is:
False
Por otro lado, si el archivo contiene la base de conocimiento según la sintaxis de Prover9 (teniendo en cuenta que sólo trabaja con lógica proposicional), las funciones son:
*MainFunctions> formulas "exFORMULAS/easy/example1.txt"
(fromList [-(p4 -> p1),(p3 & p1),(p1 | p2),(p1 | -p3)],["p4","p1","p3","p2"])
*MainFunctions> satFORMULAS "exFORMULAS/easy/example1.txt" frequency
The satisfactibility of instance exFORMULAS/easy/example1.txt is:
False
La herramienta stack incluye la posibilidad de crear accesos directos a ciertas funciones. Aprovechando esto se han definido dos distintos en función del fichero de entrada. Si el conjunto de fórmulas está en formato DIMACS el ejecutable que se debe usar se llama satCNF, seguido del fichero que se quiere usar, así como de la heurística escogida:
MacBook-Air-de-Daniel:SAT-canonical danrodcha$ stack build MacBook-Air-de-Daniel:SAT-canonical danrodcha$ stack exec satCNF exDIMACS/medium/exampleSat0.txt frequency The satisfactibility of instance exDIMACS/medium/exampleSat0.txt is: True
Si el conjunto de fórmulas sigue la sintaxis de Prove9, el ejecutable que se debe usar se llama sat, y debe ir seguido del fichero que se quiere usar, así como de la heurística escogida:
MacBook-Air-de-Daniel:SAT-canonical danrodcha$ stack build MacBook-Air-de-Daniel:SAT-Pol danrodcha$ stack exec sat exFORMULAS/easy/example1.txt frequency The satisfactibility of instance exFORMULAS/easy/example1.txt solved by frequency heuristics is: False
Este repositorio incluye la funcionalidad de calcular bases débiles. La función que las calcula recibe como entrada la base de conocimiento y una lista con todas las variables que ocurren en ella.
Para más información sobre las bases débiles ver here? .
*MainFunctions> (kb,vs) <- formulas "exFORMULAS/article/example-4-1.txt"
*MainFunctions> kb
fromList [((t & p) -> s),((t & q) -> s),((t & r) -> s),(((p & q) & t) -> r)]
*MainFunctions> vs
["t","p","s","q","r"]
*MainFunctions> weakBasis kb vs
[["s","r"],["s","q"],["p","q","r"],["p","s"],["t"]]
A fin de facilitar la labor al usuario, se incluye la posibilidad de calcular directamente una base débil de una KB almacenada en un fichero de texto (en uno de los formatos ya comentados).