
    cwiy3                         S r SSKJrJrJrJrJrJr  SSKJ	r	J
r
Jr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  S/r\\\\4   r " S S5      r " S S5      rg)a
  
This module defines the `Theory` class for using a [CFFI] based module with
clingo's Python package.

[CFFI]: https://cffi.readthedocs.io/en/latest/

Example
-------

```python
>>> from clingo import Control
>>> from clingo.ast import parse_string, ProgramBuilder
>>> from clingo.theory import Theory
>>> from clingcon._clingcon import lib, ffi
>>>
>>> prg = '&sum { x } >= 1. &sum { x } <= 3.'
>>>
>>> thy = Theory('clingcon', lib, ffi)
>>> ctl = Control(['0'])
>>> thy.register(ctl)
>>> with ProgramBuilder(ctl) as bld:
...     parse_string(prg, lambda ast: thy.rewrite_ast(ast, bld.add))
...
>>> ctl.ground([('base', [])])
>>> thy.prepare(ctl)
>>> with ctl.solve(yield_=True, on_model=thy.on_model) as hnd:
...     for mdl in hnd:
...         print([f'{key}={val}' for key, val in thy.assignment(mdl.thread_id)])
...
['x=1']
['x=2']
['x=3']
```

Notes
-----
The CFFI module must provide the following functions and data structures, where
`PREFIX` corresponds to the prefix string passed to the `Theory` constructor:

```c
enum PREFIX_value_type {
    PREFIX_value_type_int = 0,
    PREFIX_value_type_double = 1,
    PREFIX_value_type_symbol = 2
};
typedef int PREFIX_value_type_t;
typedef struct PREFIX_value {
    PREFIX_value_type_t type;
    union {
        int int_number;
        double double_number;
        clingo_symbol_t symbol;
    };
} PREFIX_value_t;
typedef bool (*PREFIX_ast_callback_t)(clingo_ast_t *ast, void *data);

bool PREFIX_create(PREFIX_theory_t **theory)
bool PREFIX_destroy(PREFIX_theory_t *theory)
bool PREFIX_version(PREFIX_theory_t **theory, int *major, int *minor, int *patch);
bool PREFIX_register(PREFIX_theory_t *theory, clingo_control_t* control)
bool PREFIX_rewrite_ast(PREFIX_theory_t *theory, clingo_ast_t *ast, PREFIX_ast_callback_t add, void *data);
bool PREFIX_prepare(PREFIX_theory_t *theory, clingo_control_t* control)
bool PREFIX_register_options(PREFIX_theory_t *theory, clingo_options_t* options)
bool PREFIX_validate_options(PREFIX_theory_t *theory)
bool PREFIX_on_model(PREFIX_theory_t *theory, clingo_model_t* model)
bool PREFIX_on_statistics(PREFIX_theory_t *theory, clingo_statistics_t* step, clingo_statistics_t* accu)
bool PREFIX_lookup_symbol(PREFIX_theory_t *theory, clingo_symbol_t symbol, size_t *index)
clingo_symbol_t PREFIX_get_symbol(PREFIX_theory_t *theory, size_t index)
void PREFIX_assignment_begin(PREFIX_theory_t *theory, uint32_t thread_id, size_t *index)
bool PREFIX_assignment_next(PREFIX_theory_t *theory, uint32_t thread_id, size_t *index)
bool PREFIX_assignment_has_value(PREFIX_theory_t *theory, uint32_t thread_id, size_t index)
void PREFIX_assignment_get_value(PREFIX_theory_t *theory, uint32_t thread_id, size_t index, PREFIX_value_t *value)
bool PREFIX_configure(PREFIX_theory_t *theory, char const *key, char const *value)
```
    )AnyCallableIteratorOptionalTupleUnion   )_ffi_handle_error_lib)ApplicationOptions)AST)Control)Model)StatisticsMap)SymbolTheoryc                       \ rS rSrSrS rSrg)_CBData\   z
The class stores the data object that should be passed to a callback as
well as provides the means to set an error while a callback is running.
c                     Xl         S U l        g Ndataerror)selfr   s     G/home/james-whalen/.local/lib/python3.13/site-packages/clingo/theory.py__init___CBData.__init__b   s    	
    r   N)__name__
__module____qualname____firstlineno____doc__r   __static_attributes__ r    r   r   r   \   s    
r    r   c                      \ rS rSrSrS\S\S\4S jrS,S jrS,S jr	S	\
4S
 jrS rS rS rS rS rS	\\\\4   4S jrS\S\S	S4S jrS\S	S4S jrS\S	S4S jrS\S\\/S4   S	S4S jrS\S	S4S jrS-S jrS\S	S4S jrS \ S!\ S	S4S" jr!S#\"S	\#\   4S$ jr$S%\S	\"4S& jr%S'\S%\S	\
4S( jr&S'\S%\S	\'4S) jr(S'\S	\)\\"\'4      4S* jr*S+r+g).r   g   z
Interface to call functions from a C-library extending clingo's C/Python
library.

The functions in here are designed to be used with a `Application`
object but can also be used with a standalone `Control` object.
prefixlibffic                     Xl         X l        X0l        U R                  U R	                  S5      S5      U l        U R                  5       U l        g)a  
Loads a given library.

Arguments
---------
prefix
    Prefix of functions and data structures in the library.
lib
    [A CFFI lib object](https://cffi.readthedocs.io/en/latest/using.html).
ffi
    [A CFFI ffi object](https://cffi.readthedocs.io/en/latest/ref.html).
z	theory_t*createN)_prer   r
   _Theory__call1_Theory__pre_theory_Theory__define_rewrite_rewrite)r   r*   r+   r,   s       r   r   Theory.__init__r   s>     			||DJJ{$;XF--/r    c                 (    U U R                    SU 3$ )N_)r/   r   nameextras      r   __preTheory.__pre   s    1TF++r    c                 L    [        U R                  U R                  X5      5      $ r   )getattrr   r1   r8   s      r   __getTheory.__get   s    tyy$**T"9::r    returnc                 `   Ubx  U R                   R                  UR                  R                  S   5      nXU4Ul        [
        R                  " [
        R                  [        U5      R                  5       5        g[
        R                  " [
        R                  SR                  5       5        g)Nr   zerror in callbackF)r
   from_handletb_framef_localsr   r   clingo_set_errorclingo_error_unknownstrencodeclingo_error_runtime)r   	exception	exc_value	tracebackcb_datas        r   __error_handlerTheory.__error_handler   s     ii++I,>,>,G,G,OPG&9=GM!!$";";S^=R=R=TU
  !!))+>+E+E+G r    c                    ^  T R                   R                  T R                  SS5      T R                  S9U 4S j5       nU$ )Nrewritepy)r9   onerrorc                    > TR                   R                  U5      R                  n[         R                  " SU 5      n [        R
                  " U 5        U" [        U 5      5        g)Nclingo_ast_t*T)r
   rC   r   castr   clingo_ast_acquirer   )astr   addr   s      r   rR   (Theory.__define_rewrite.<locals>.rewrite   sK     ))''-22C))OS1C##C(CMr    )r
   
def_externr1   _Theory__error_handler)r   rR   s   ` r   __define_rewriteTheory.__define_rewrite   sF    			It,d6J6J 
 

	

	 r    c                 *    U R                  U5      " U6 $ )z@
Helper to simplify calling C functions without error handling.
)_Theory__getr   c_funargss      r   __callTheory.__call   s     zz% $''r    c                 <    [        U R                  " U/UQ76 5        g)z@
Helper to simplify calling C functions without a return value.
N)r   _Theory__callrb   s      r   __call0Theory.__call0   s     	dkk%/$/0r    c                     [        U[        5      (       a  U R                  R                  U S35      nOUn[	        U R
                  " U/UQUP76 5        US   $ )ze
Helper to simplify calling C functions where the last parameter is a
reference to the return value.
*r   )
isinstancerH   r
   newr   rh   )r   c_typerc   rd   p_rets        r   __call1Theory.__call1   sR    
 fc""IIMMVHA,/EEdkk%6$667Qxr    c                 f    U R                   b$  U R                  SU R                   5        S U l         g g )Ndestroy)r2   _Theory__call0r   s    r   __del__Theory.__del__   s*    <<#LLDLL1DL $r    c                     U R                   R                  S5      nU R                  SXS-   US-   5        US   US   US   4$ )z
This function returns the version of the theory.

Returns
-------
A 3-tuple of integers representing major and minor version as well as
the patch level.
zint[3]versionr	      r   )r
   rn   rh   )r   	p_versions     r   rz   Theory.version   sG     IIMM(+	Iya-QG|Yq\9Q<77r    keyvalueNc                 x    U R                  SU R                  UR                  5       UR                  5       5        g)z
Allows for configuring a theory via key/value pairs similar to
command line options.

This function must be called before the theory is registered.

Arguments
---------
key
    The name of the option.
value
    The value of the option.
	configureN)ru   r2   rI   )r   r~   r   s      r   r   Theory.configure   s&     	[$,,

ellnMr    controlc                     U R                  SU R                  U R                  R                  SUR                  5      5        g)zn
Register the theory with the given control object.

Arguments
---------
control
    Target to register with.
registerclingo_control_t*Nru   r2   r
   rW   _repr   r   s     r   r   Theory.register   s/     	diinn5H',,&W	
r    c                     U R                  SU R                  U R                  R                  SUR                  5      5        g)z
Prepare the theory.

Must be called between ground and solve.

Arguments
---------
control
    The associated control object.
preparer   Nr   r   s     r   r   Theory.prepare   s/     	t||TYY^^4G%V	
r    stmrZ   c           	          [        U5      nU R                  R                  U5      nU R                  SU R                  U R                  R                  SUR                  5      U R                  SS5      U5        g)z
Rewrite the given statement and call add on the rewritten version(s).

Must be called for some theories that have to perform rewritings on the
AST.

Arguments
---------
stm
    Statement to translate.
add
    Callback for adding translated statements.
rewrite_astrV   rR   rS   N)r   r
   
new_handleru   r2   rW   r   ra   )r   r   rZ   rN   handles        r   r   Theory.rewrite_ast   s^     #,%%g.LLIINN?CHH5JJy$'	
r    optionsc                     U R                  SU R                  U R                  R                  SUR                  5      5        g)z
Register the theory's options with the given application options
object.

Arguments
---------
options
    Target to register with.
register_optionszclingo_options_t*Nr   )r   r   s     r   r   Theory.register_options  s1     	LLIINN.=	
r    c                 <    U R                  SU R                  5        g)z%
Validate the options of the theory.
validate_optionsN)ru   r2   rv   s    r   r   Theory.validate_options"  s     	'6r    modelc                     U R                  SU R                  U R                  R                  SUR                  5      5        g)zb
Inform the theory that a model has been found.

Arguments
---------
model
    The current model.
on_modelzclingo_model_t*Nr   )r   r   s     r   r   Theory.on_model(  s/     	diinn5F

&S	
r    stepaccuc           	          U R                  SU R                  U R                  R                  SUR                  5      U R                  R                  SUR                  5      5        g)z
Add the theory's statistics to the given maps.

Arguments
---------
step: StatisticsMap
    Map for per step statistics.
accu: StatisticsMap
    Map for accumulated statistics.
on_statisticszclingo_statistics_t*Nr   )r   r   r   s      r   r   Theory.on_statistics5  sH     	LLIINN1499=IINN1499=		
r    symbolc                     U R                   R                  S5      nU R                  SU R                  UR                  U5      (       a  US   $ g)z
Get the integer index of a symbol assigned by the theory when a
model is found.

Using indices allows for efficent retrieval of values.

Arguments
---------
symbol
    The symbol to look up.

Returns
-------
The index of the value if found.
size_t*lookup_symbolr   N)r
   rn   rh   r2   r   )r   r   c_indexs      r   r   Theory.lookup_symbolG  s@      ))--	*;;fkk7KK1:r    indexc           
      x    [        [        R                  " SU R                  SU R                  U5      5      5      $ )z
Get the symbol associated with an index.

The index must be valid.

Arguments
---------
index
    Index to retreive.

Returns
-------
The associated symbol.
clingo_symbol_t
get_symbol)r   r
   rW   rh   r2   )r   r   s     r   r   Theory.get_symbol\  s2     II'\4<<QV)WX
 	
r    	thread_idc                 <    U R                  SU R                  X5      $ )z
Check if the given symbol index has a value in the current model.

Arguments
---------
thread_id
    The index of the solving thread that found the model.
index
    Index to retreive.

Returns
-------
Whether the given index has a value.
assignment_has_value)rh   r2   )r   r   r   s      r   	has_valueTheory.has_valueo  s     {{14<<RRr    c                 b   U R                   R                  U R                  S5      5      nU R                  SU R                  XU5        UR
                  S:X  a  UR                  $ UR
                  S:X  a  UR                  $ UR
                  S:X  a  [        UR                  5      $ [        S5      e)z
Get the value of the symbol index in the current model.

Arguments
---------
thread_id
    The index of the solving thread that found the model.
index
    Index to retreive.

Returns
-------
The value of the index in form of an int, float, or Symbol.
zvalue_t*assignment_get_valuer   r	   r{   zmust not happen)r
   rn   r1   rh   r2   type
int_numberdouble_numberr   r   RuntimeError)r   r   r   c_values       r   	get_valueTheory.get_value  s     ))--

: 67*DLL)GT<<1%%%<<1(((<<1'..)),--r    c              #   ^  #    U R                   R                  S5      nU R                  SU R                  X5        U R                  SU R                  X5      (       aO  U R	                  US   5      U R                  XS   5      4v   U R                  SU R                  X5      (       a  MN  gg7f)z
Get all values symbol/value pairs assigned by the theory in the
current model.

Arguments
---------
thread_id
    The index of the solving thread that found the model.

Returns
-------
An iterator over symbol/value pairs.
r   assignment_beginassignment_nextr   N)r
   rn   rh   r2   r   r   )r   r   r   s      r   
assignmentTheory.assignment  s      ))--	*&iIkk+T\\9NN??71:.yRS*0UVV kk+T\\9NNs   B'B-+B-)r
   r   r/   r4   r2   ) )rA   N),r!   r"   r#   r$   r%   rH   r   r   r1   ra   boolr]   r3   rh   ru   r0   rw   r   intrz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   	ValueTyper   r   r   r&   r'   r    r   r   r   g   s   0s 0 03 0&,;	$ 	(1
 
8sC}- 8NS N N N 
 
D 

w 
4 

s 
3%+)> 
4 
2
(: 
t 
 7
e 
 

- 
} 
 
$F x} *
 
 
&S3 Ss St S".3 .s .y .2WC WHU69;L5M,N Wr    N)r%   typingr   r   r   r   r   r   	_internalr
   r   r   applicationr   rY   r   r   r   solvingr   
statisticsr   r   r   __all__r   floatr   r   r   r'   r    r   <module>r      s]   JX C B 0 0 +    % *#uf$%	 CW CWr    