3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-01 03:41:21 +00:00
z3/src/api/dotnet/ASTMap.cs
Nikolaj Bjorner edeeded4ea
remove DecRefQueue, use Z3_enable_concurrent_dec_ref (#6332)
The notion of reference counted contexts never worked.
The reference count to a context only ends up being 0 if the GC kicks in and disposes the various z3 objects. A call to Dispose on Context should free up all resources associated with that context. In exchange none of the resources are allowed any other operation than DecRef. The invocations of DecRef are protected by a lock and test on the context that the native pointer associated with the context is non-zero. Dispose sets the native pointer to zero.

Z3_enable_concurrent_dec_ref ensures that:

- calls to decref are thread safe. Other threads can operate on the context without interference.

The Z3_context ensures that
- z3objects allocated, but not disposed during the lifetime of Z3_context are freed when Z3_context is deleted (it triggers a debug warning, but this is now benign).
2022-09-11 18:59:00 -07:00

143 lines
3.7 KiB
C#

/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
ASTMap.cs
Abstract:
Z3 Managed API: AST Maps
Author:
Christoph Wintersteiger (cwinter) 2012-03-21
Notes:
--*/
using System.Diagnostics;
using System;
namespace Microsoft.Z3
{
/// <summary>
/// Map from AST to AST
/// </summary>
internal class ASTMap : Z3Object
{
/// <summary>
/// Checks whether the map contains the key <paramref name="k"/>.
/// </summary>
/// <param name="k">An AST</param>
/// <returns>True if <paramref name="k"/> is a key in the map, false otherwise.</returns>
public bool Contains(AST k)
{
Debug.Assert(k != null);
return 0 != Native.Z3_ast_map_contains(Context.nCtx, NativeObject, k.NativeObject);
}
/// <summary>
/// Finds the value associated with the key <paramref name="k"/>.
/// </summary>
/// <remarks>
/// This function signs an error when <paramref name="k"/> is not a key in the map.
/// </remarks>
/// <param name="k">An AST</param>
public AST Find(AST k)
{
Debug.Assert(k != null);
return new AST(Context, Native.Z3_ast_map_find(Context.nCtx, NativeObject, k.NativeObject));
}
/// <summary>
/// Stores or replaces a new key/value pair in the map.
/// </summary>
/// <param name="k">The key AST</param>
/// <param name="v">The value AST</param>
public void Insert(AST k, AST v)
{
Debug.Assert(k != null);
Debug.Assert(v != null);
Native.Z3_ast_map_insert(Context.nCtx, NativeObject, k.NativeObject, v.NativeObject);
}
/// <summary>
/// Erases the key <paramref name="k"/> from the map.
/// </summary>
/// <param name="k">An AST</param>
public void Erase(AST k)
{
Debug.Assert(k != null);
Native.Z3_ast_map_erase(Context.nCtx, NativeObject, k.NativeObject);
}
/// <summary>
/// Removes all keys from the map.
/// </summary>
public void Reset()
{
Native.Z3_ast_map_reset(Context.nCtx, NativeObject);
}
/// <summary>
/// The size of the map
/// </summary>
public uint Size
{
get { return Native.Z3_ast_map_size(Context.nCtx, NativeObject); }
}
/// <summary>
/// The keys stored in the map.
/// </summary>
public AST[] Keys
{
get
{
using ASTVector res = new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject));
return res.ToArray();
}
}
/// <summary>
/// Retrieves a string representation of the map.
/// </summary>
public override string ToString()
{
return Native.Z3_ast_map_to_string(Context.nCtx, NativeObject);
}
#region Internal
internal ASTMap(Context ctx, IntPtr obj)
: base(ctx, obj)
{
Debug.Assert(ctx != null);
}
internal ASTMap(Context ctx)
: base(ctx, Native.Z3_mk_ast_map(ctx.nCtx))
{
Debug.Assert(ctx != null);
}
internal override void IncRef(IntPtr o)
{
Native.Z3_ast_map_inc_ref(Context.nCtx, o);
}
internal override void DecRef(IntPtr o)
{
lock (Context)
{
if (Context.nCtx != IntPtr.Zero)
Native.Z3_ast_map_dec_ref(Context.nCtx, o);
}
}
#endregion
}
}