<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include <array>
#include <cstdint>
#include <string>
#include <type_traits>

#include <caf/intrusive_ptr.hpp>
#include <caf/make_counted.hpp>
#include <caf/ref_counted.hpp>
#include <caf/variant.hpp>

#include "vast/aliases.hpp"
#include "vast/data.hpp"
#include "vast/fwd.hpp"
#include "vast/time.hpp"

#include "vast/detail/assert.hpp"
#include "vast/detail/iterator.hpp"
#include "vast/detail/operators.hpp"
#include "vast/detail/type_traits.hpp"

namespace vast {

/// A type-safe overlay over an immutable sequence of bytes.
template <class>
struct view_trait;

/// @relates view_trait
template <class T>
using view = typename view_trait<T>::type;

#define VAST_VIEW_TRAIT(type_name)                                             \
  inline auto materialize(type_name x) {                                       \
    return x;                                                                  \
  }                                                                            \
  template <>                                                                  \
  struct view_trait<type_name> {                                               \
    using type = type_name;                                                    \
  }

VAST_VIEW_TRAIT(bool);
VAST_VIEW_TRAIT(integer);
VAST_VIEW_TRAIT(count);
VAST_VIEW_TRAIT(real);
VAST_VIEW_TRAIT(duration);
VAST_VIEW_TRAIT(time);
VAST_VIEW_TRAIT(enumeration);
VAST_VIEW_TRAIT(port);
VAST_VIEW_TRAIT(address);
VAST_VIEW_TRAIT(subnet);

#undef VAST_VIEW_TRAIT

/// @relates view_trait
template <>
struct view_trait<caf::none_t> {
  using type = caf::none_t;
};

/// @relates view_trait
template <>
struct view_trait<std::string> {
  using type = std::string_view;
};

/// @relates view_trait
class pattern_view : detail::totally_ordered<pattern_view> {
public:
  static pattern glob(std::string_view x);

  pattern_view(const pattern& x);

  explicit pattern_view(std::string_view str);

  bool match(std::string_view x) const;
  bool search(std::string_view x) const;
  std::string_view string() const;

private:
  std::string_view pattern_;
};

/// @relates pattern_view
bool operator==(pattern_view x, pattern_view y) noexcept;

/// @relates pattern_view
bool operator<(pattern_view x, pattern_view y) noexcept;

//// @relates view_trait
template <>
struct view_trait<pattern> {
  using type = pattern_view;
};

template <class T>
class container_view_handle;

struct vector_view_ptr;
struct set_view_ptr;
struct map_view_ptr;

// @relates view_trait
using vector_view_handle = container_view_handle<vector_view_ptr>;

// @relates view_trait
using set_view_handle = container_view_handle<set_view_ptr>;

// @relates view_trait
using map_view_handle = container_view_handle<map_view_ptr>;

/// @relates view_trait
template <>
struct view_trait<vector> {
  using type = vector_view_handle;
};

/// @relates view_trait
template <>
struct view_trait<set> {
  using type = set_view_handle;
};

/// @relates view_trait
template <>
struct view_trait<map> {
  using type = map_view_handle;
};

// clang-format off
/// A type-erased view over variout types of data.
/// @relates view_trait
using data_view = caf::variant<
  view<caf::none_t>,
  view<bool>,
  view<integer>,
  view<count>,
  view<real>,
  view<duration>,
  view<time>,
  view<std::string>,
  view<pattern>,
  view<address>,
  view<subnet>,
  view<port>,
  view<enumeration>,
  view<vector>,
  view<set>,
  view<map>
>;
// clang-format on

/// @relates view_trait
template <>
struct view_trait<data> {
  using type = data_view;
};

template <class T>
struct container_view;

/// @relates view_trait
template <class T>
using container_view_ptr = caf::intrusive_ptr<container_view<T>>;

/// @relates container_view
template <class Pointer>
class container_view_handle
  : detail::totally_ordered<container_view_handle<Pointer>> {
public:
  using view_type = typename Pointer::element_type;

  using iterator = typename view_type::iterator;

  container_view_handle() = default;

  container_view_handle(Pointer ptr) : ptr_{ptr} {
    // nop
  }

  explicit operator bool() const {
    return static_cast<bool>(ptr_);
  }

  auto operator->() const {
    return ptr_.get();
  }

  const auto& operator*() const {
    return *ptr_;
  }

  iterator begin() const {
    return {ptr_.get(), 0};
  }

  iterator end() const {
    return {ptr_.get(), size()};
  }

  size_t size() const {
    return ptr_ ? ptr_->size() : 0;
  }

  bool empty() const {
    return size() == 0;
  }

private:
  Pointer ptr_;
};

template <class Pointer>
bool operator==(const container_view_handle<Pointer>& x,
                const container_view_handle<Pointer>& y) {
  return x && y && *x == *y;
}

template <class Pointer>
bool operator<(const container_view_handle<Pointer>& x,
               const container_view_handle<Pointer>& y) {
  if (!x)
    return static_cast<bool>(y);
  if (!y)
    return false;
  return *x < *y;
}

namespace detail {

/// @relates view_trait
template <class T>
class container_view_iterator
  : public detail::iterator_facade<
      container_view_iterator<T>,
      T,
      std::random_access_iterator_tag,
      T
    > {
  friend iterator_access;

public:
  container_view_iterator(typename container_view_ptr<T>::const_pointer ptr,
                          size_t pos)
    : view_{ptr}, position_{pos} {
    // nop
  }

  auto dereference() const {
    return view_->at(position_);
  }

  void increment() {
    ++position_;
  }

  void decrement() {
    --position_;
  }

  template <class N>
  void advance(N n) {
    position_ += n;
  }

  bool equals(container_view_iterator other) const {
    return view_ == other.view_ && position_ == other.position_;
  }

  auto distance_to(container_view_iterator other) const {
    return other.position_ - position_;
  }

private:
  typename container_view_ptr<T>::const_pointer view_;
  size_t position_;
};

} // namespace detail

/// Base class for container views.
/// @relates view_trait
template <class T>
struct container_view
  : caf::ref_counted,
    detail::totally_ordered<container_view<T>> {
  using value_type = T;
  using size_type = size_t;
  using iterator = detail::container_view_iterator<T>;
  using const_iterator = iterator;

  virtual ~container_view() = default;

  iterator begin() const {
    return {this, 0};
  }

  iterator end() const {
    return {this, size()};
  }

  /// Retrieves a specific element.
  /// @param i The position of the element to retrieve.
  /// @returns A view to the element at position *i*.
  virtual value_type at(size_type i) const = 0;

  /// @returns The number of elements in the container.
  virtual size_type size() const noexcept = 0;

  /// @returns `true` if the container is empty.
  bool empty() const noexcept {
    return size() == 0;
  }
};

template <class T>
bool operator==(const container_view<T>& xs, const container_view<T>& ys) {
  if (xs.size() != ys.size())
    return false;
  for (auto i = 0u; i < xs.size(); ++i)
    if (xs.at(i) != ys.at(i))
      return false;
  return true;
}

template <class T>
bool operator<(const container_view<T>& xs, const container_view<T>& ys) {
  if (xs.size() != ys.size())
    return xs.size() < ys.size();
  for (auto i = 0u; i < xs.size(); ++i)
    if (xs.at(i) < ys.at(i))
      return true;
  return false;
}

// @relates view_trait
struct vector_view_ptr : container_view_ptr<data_view> {};

// @relates view_trait
struct set_view_ptr : container_view_ptr<data_view> {};

// @relates view_trait
struct map_view_ptr : container_view_ptr<std::pair<data_view, data_view>> {};

/// A view over a @ref vector.
/// @relates view_trait
class default_vector_view
  : public container_view<data_view>,
    detail::totally_ordered<default_vector_view> {
public:
  default_vector_view(const vector& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const vector& xs_;
};

/// A view over a @ref set.
/// @relates view_trait
class default_set_view
  : public container_view<data_view>,
    detail::totally_ordered<default_set_view> {
public:
  default_set_view(const set& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const set& xs_;
};

/// A view over a @ref map.
/// @relates view_trait
class default_map_view
  : public container_view<std::pair<data_view, data_view>>,
    detail::totally_ordered<default_map_view> {
public:
  default_map_view(const map& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const map& xs_;
};

/// Creates a view from a specific type.
/// @relates view_trait
template <class T>
view<T> make_view(const T& x) {
  constexpr auto directly_constructible = detail::is_any_v<
    T, caf::none_t, bool, integer, count, real, duration, time, std::string,
    pattern, address, subnet, port, enumeration>;
  if constexpr (directly_constructible) {
    return x;
  } else if constexpr (std::is_same_v<T, vector>) {
    return vector_view_ptr{caf::make_counted<default_vector_view>(x)};
  } else if constexpr (std::is_same_v<T, set>) {
    return set_view_ptr{caf::make_counted<default_set_view>(x)};
  } else if constexpr (std::is_same_v<T, map>) {
    return map_view_ptr{caf::make_counted<default_map_view>(x)};
  } else {
    VAST_ASSERT(!"missing branch");
    return {};
  }
}

/// Creates a view from a string literal.
/// @relates view_trait
template <size_t N>
view<std::string> make_view(const char (&xs)[N]) {
  return std::string_view(xs, N - 1);
}

/// Creates a view from a `std::string_view`.
/// @relates view_trait
constexpr view<std::string> make_view(std::string_view xs) {
  return xs;
}

/// @relates view data
data_view make_view(const data& x);

/// Creates a type-erased data view from a specific type.
/// @relates view_trait
template <class T>
data_view make_data_view(const T& x) {
  return make_view(x);
}

/// @relates view_trait
template <class T>
data_view make_data_view(const optional<T>& x) {
  if (!x)
    return make_view(caf::none);
  return make_view(*x);
}

// -- materialization ----------------------------------------------------------

constexpr auto materialize(caf::none_t x) {
  return x;
}

std::string materialize(std::string_view x);

pattern materialize(pattern_view x);

vector materialize(vector_view_handle xs);

set materialize(set_view_handle xs);

map materialize(map_view_handle xs);

data materialize(data_view xs);

// -- utilities ----------------------------------------------------------------

/// Checks whether data is valid for a given type.
/// @param t The type that describes *d*.
/// @param x The data view to be checked against *t*.
/// @returns `true` if *t* is a valid type for *x*.
bool type_check(const type& t, const data_view& x);

/// Evaluates a data predicate.
/// @param lhs The LHS of the predicate.
/// @param op The relational operator.
/// @param rhs The RHS of the predicate.
/// @note This function unfortunately needs to use the `_view` suffix because
///       it otherwise produces ambiguous function calls with the `evaluate`
///       function in `data.hpp`.
bool evaluate_view(const data_view& lhs, relational_operator op,
                   const data_view& rhs);

} // namespace vast
<commit_msg>Fix materialize function<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#pragma once

#include <array>
#include <cstdint>
#include <string>
#include <type_traits>

#include <caf/intrusive_ptr.hpp>
#include <caf/make_counted.hpp>
#include <caf/ref_counted.hpp>
#include <caf/variant.hpp>

#include "vast/aliases.hpp"
#include "vast/data.hpp"
#include "vast/fwd.hpp"
#include "vast/time.hpp"

#include "vast/detail/assert.hpp"
#include "vast/detail/iterator.hpp"
#include "vast/detail/operators.hpp"
#include "vast/detail/type_traits.hpp"

namespace vast {

/// A type-safe overlay over an immutable sequence of bytes.
template <class>
struct view_trait;

/// @relates view_trait
template <class T>
using view = typename view_trait<T>::type;

#define VAST_VIEW_TRAIT(type_name)                                             \
  template <>                                                                  \
  struct view_trait<type_name> {                                               \
    using type = type_name;                                                    \
  };                                                                           \
  inline type_name materialize(view<type_name> x) {                            \
    return x;                                                                  \
  }

VAST_VIEW_TRAIT(bool)
VAST_VIEW_TRAIT(integer)
VAST_VIEW_TRAIT(count)
VAST_VIEW_TRAIT(real)
VAST_VIEW_TRAIT(duration)
VAST_VIEW_TRAIT(time)
VAST_VIEW_TRAIT(enumeration)
VAST_VIEW_TRAIT(port)
VAST_VIEW_TRAIT(address)
VAST_VIEW_TRAIT(subnet)

#undef VAST_VIEW_TRAIT

/// @relates view_trait
template <>
struct view_trait<caf::none_t> {
  using type = caf::none_t;
};

/// @relates view_trait
template <>
struct view_trait<std::string> {
  using type = std::string_view;
};

/// @relates view_trait
class pattern_view : detail::totally_ordered<pattern_view> {
public:
  static pattern glob(std::string_view x);

  pattern_view(const pattern& x);

  explicit pattern_view(std::string_view str);

  bool match(std::string_view x) const;
  bool search(std::string_view x) const;
  std::string_view string() const;

private:
  std::string_view pattern_;
};

/// @relates pattern_view
bool operator==(pattern_view x, pattern_view y) noexcept;

/// @relates pattern_view
bool operator<(pattern_view x, pattern_view y) noexcept;

//// @relates view_trait
template <>
struct view_trait<pattern> {
  using type = pattern_view;
};

template <class T>
class container_view_handle;

struct vector_view_ptr;
struct set_view_ptr;
struct map_view_ptr;

// @relates view_trait
using vector_view_handle = container_view_handle<vector_view_ptr>;

// @relates view_trait
using set_view_handle = container_view_handle<set_view_ptr>;

// @relates view_trait
using map_view_handle = container_view_handle<map_view_ptr>;

/// @relates view_trait
template <>
struct view_trait<vector> {
  using type = vector_view_handle;
};

/// @relates view_trait
template <>
struct view_trait<set> {
  using type = set_view_handle;
};

/// @relates view_trait
template <>
struct view_trait<map> {
  using type = map_view_handle;
};

// clang-format off
/// A type-erased view over variout types of data.
/// @relates view_trait
using data_view = caf::variant<
  view<caf::none_t>,
  view<bool>,
  view<integer>,
  view<count>,
  view<real>,
  view<duration>,
  view<time>,
  view<std::string>,
  view<pattern>,
  view<address>,
  view<subnet>,
  view<port>,
  view<enumeration>,
  view<vector>,
  view<set>,
  view<map>
>;
// clang-format on

/// @relates view_trait
template <>
struct view_trait<data> {
  using type = data_view;
};

template <class T>
struct container_view;

/// @relates view_trait
template <class T>
using container_view_ptr = caf::intrusive_ptr<container_view<T>>;

/// @relates container_view
template <class Pointer>
class container_view_handle
  : detail::totally_ordered<container_view_handle<Pointer>> {
public:
  using view_type = typename Pointer::element_type;

  using iterator = typename view_type::iterator;

  container_view_handle() = default;

  container_view_handle(Pointer ptr) : ptr_{ptr} {
    // nop
  }

  explicit operator bool() const {
    return static_cast<bool>(ptr_);
  }

  auto operator->() const {
    return ptr_.get();
  }

  const auto& operator*() const {
    return *ptr_;
  }

  iterator begin() const {
    return {ptr_.get(), 0};
  }

  iterator end() const {
    return {ptr_.get(), size()};
  }

  size_t size() const {
    return ptr_ ? ptr_->size() : 0;
  }

  bool empty() const {
    return size() == 0;
  }

private:
  Pointer ptr_;
};

template <class Pointer>
bool operator==(const container_view_handle<Pointer>& x,
                const container_view_handle<Pointer>& y) {
  return x && y && *x == *y;
}

template <class Pointer>
bool operator<(const container_view_handle<Pointer>& x,
               const container_view_handle<Pointer>& y) {
  if (!x)
    return static_cast<bool>(y);
  if (!y)
    return false;
  return *x < *y;
}

namespace detail {

/// @relates view_trait
template <class T>
class container_view_iterator
  : public detail::iterator_facade<
      container_view_iterator<T>,
      T,
      std::random_access_iterator_tag,
      T
    > {
  friend iterator_access;

public:
  container_view_iterator(typename container_view_ptr<T>::const_pointer ptr,
                          size_t pos)
    : view_{ptr}, position_{pos} {
    // nop
  }

  auto dereference() const {
    return view_->at(position_);
  }

  void increment() {
    ++position_;
  }

  void decrement() {
    --position_;
  }

  template <class N>
  void advance(N n) {
    position_ += n;
  }

  bool equals(container_view_iterator other) const {
    return view_ == other.view_ && position_ == other.position_;
  }

  auto distance_to(container_view_iterator other) const {
    return other.position_ - position_;
  }

private:
  typename container_view_ptr<T>::const_pointer view_;
  size_t position_;
};

} // namespace detail

/// Base class for container views.
/// @relates view_trait
template <class T>
struct container_view
  : caf::ref_counted,
    detail::totally_ordered<container_view<T>> {
  using value_type = T;
  using size_type = size_t;
  using iterator = detail::container_view_iterator<T>;
  using const_iterator = iterator;

  virtual ~container_view() = default;

  iterator begin() const {
    return {this, 0};
  }

  iterator end() const {
    return {this, size()};
  }

  /// Retrieves a specific element.
  /// @param i The position of the element to retrieve.
  /// @returns A view to the element at position *i*.
  virtual value_type at(size_type i) const = 0;

  /// @returns The number of elements in the container.
  virtual size_type size() const noexcept = 0;

  /// @returns `true` if the container is empty.
  bool empty() const noexcept {
    return size() == 0;
  }
};

template <class T>
bool operator==(const container_view<T>& xs, const container_view<T>& ys) {
  if (xs.size() != ys.size())
    return false;
  for (auto i = 0u; i < xs.size(); ++i)
    if (xs.at(i) != ys.at(i))
      return false;
  return true;
}

template <class T>
bool operator<(const container_view<T>& xs, const container_view<T>& ys) {
  if (xs.size() != ys.size())
    return xs.size() < ys.size();
  for (auto i = 0u; i < xs.size(); ++i)
    if (xs.at(i) < ys.at(i))
      return true;
  return false;
}

// @relates view_trait
struct vector_view_ptr : container_view_ptr<data_view> {};

// @relates view_trait
struct set_view_ptr : container_view_ptr<data_view> {};

// @relates view_trait
struct map_view_ptr : container_view_ptr<std::pair<data_view, data_view>> {};

/// A view over a @ref vector.
/// @relates view_trait
class default_vector_view
  : public container_view<data_view>,
    detail::totally_ordered<default_vector_view> {
public:
  default_vector_view(const vector& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const vector& xs_;
};

/// A view over a @ref set.
/// @relates view_trait
class default_set_view
  : public container_view<data_view>,
    detail::totally_ordered<default_set_view> {
public:
  default_set_view(const set& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const set& xs_;
};

/// A view over a @ref map.
/// @relates view_trait
class default_map_view
  : public container_view<std::pair<data_view, data_view>>,
    detail::totally_ordered<default_map_view> {
public:
  default_map_view(const map& xs);

  value_type at(size_type i) const override;

  size_type size() const noexcept override;

private:
  const map& xs_;
};

/// Creates a view from a specific type.
/// @relates view_trait
template <class T>
view<T> make_view(const T& x) {
  constexpr auto directly_constructible = detail::is_any_v<
    T, caf::none_t, bool, integer, count, real, duration, time, std::string,
    pattern, address, subnet, port, enumeration>;
  if constexpr (directly_constructible) {
    return x;
  } else if constexpr (std::is_same_v<T, vector>) {
    return vector_view_ptr{caf::make_counted<default_vector_view>(x)};
  } else if constexpr (std::is_same_v<T, set>) {
    return set_view_ptr{caf::make_counted<default_set_view>(x)};
  } else if constexpr (std::is_same_v<T, map>) {
    return map_view_ptr{caf::make_counted<default_map_view>(x)};
  } else {
    VAST_ASSERT(!"missing branch");
    return {};
  }
}

/// Creates a view from a string literal.
/// @relates view_trait
template <size_t N>
view<std::string> make_view(const char (&xs)[N]) {
  return std::string_view(xs, N - 1);
}

/// Creates a view from a `std::string_view`.
/// @relates view_trait
constexpr view<std::string> make_view(std::string_view xs) {
  return xs;
}

/// @relates view data
data_view make_view(const data& x);

/// Creates a type-erased data view from a specific type.
/// @relates view_trait
template <class T>
data_view make_data_view(const T& x) {
  return make_view(x);
}

/// @relates view_trait
template <class T>
data_view make_data_view(const optional<T>& x) {
  if (!x)
    return make_view(caf::none);
  return make_view(*x);
}

// -- materialization ----------------------------------------------------------

constexpr auto materialize(caf::none_t x) {
  return x;
}

std::string materialize(std::string_view x);

pattern materialize(pattern_view x);

vector materialize(vector_view_handle xs);

set materialize(set_view_handle xs);

map materialize(map_view_handle xs);

data materialize(data_view xs);

// -- utilities ----------------------------------------------------------------

/// Checks whether data is valid for a given type.
/// @param t The type that describes *d*.
/// @param x The data view to be checked against *t*.
/// @returns `true` if *t* is a valid type for *x*.
bool type_check(const type& t, const data_view& x);

/// Evaluates a data predicate.
/// @param lhs The LHS of the predicate.
/// @param op The relational operator.
/// @param rhs The RHS of the predicate.
/// @note This function unfortunately needs to use the `_view` suffix because
///       it otherwise produces ambiguous function calls with the `evaluate`
///       function in `data.hpp`.
bool evaluate_view(const data_view& lhs, relational_operator op,
                   const data_view& rhs);

} // namespace vast
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "meter.h"
#include "utils.h"

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <limits>

namespace fasttext {

constexpr int32_t kAllLabels = -1;
constexpr real falseNegativeScore = -1.0;

void Meter::log(
    const std::vector<int32_t>& labels,
    const Predictions& predictions) {
  nexamples_++;
  metrics_.gold += labels.size();
  metrics_.predicted += predictions.size();

  for (const auto& prediction : predictions) {
    labelMetrics_[prediction.second].predicted++;

    real score = std::min(std::exp(prediction.first), 1.0f);
    real gold = 0.0;
    if (utils::contains(labels, prediction.second)) {
      labelMetrics_[prediction.second].predictedGold++;
      metrics_.predictedGold++;
      gold = 1.0;
    }
    labelMetrics_[prediction.second].scoreVsTrue.emplace_back(score, gold);
  }

  if (falseNegativeLabels_) {
    for (const auto& label : labels) {
      labelMetrics_[label].gold++;
      if (!utils::containsSecond(predictions, label)) {
        labelMetrics_[label].scoreVsTrue.emplace_back(falseNegativeScore, 1.0);
      }
    }
  }
}

double Meter::precision(int32_t i) {
  return labelMetrics_[i].precision();
}

double Meter::recall(int32_t i) {
  return labelMetrics_[i].recall();
}

double Meter::f1Score(int32_t i) {
  return labelMetrics_[i].f1Score();
}

double Meter::precision() const {
  return metrics_.precision();
}

double Meter::recall() const {
  return metrics_.recall();
}

double Meter::f1Score() const {
  const double precision = this->precision();
  const double recall = this->recall();
  if (precision + recall != 0) {
    return 2 * precision * recall / (precision + recall);
  }
  return std::numeric_limits<double>::quiet_NaN();
}

void Meter::writeGeneralMetrics(std::ostream& out, int32_t k) const {
  out << "N"
      << "\t" << nexamples_ << std::endl;
  out << std::setprecision(3);
  out << "P@" << k << "\t" << metrics_.precision() << std::endl;
  out << "R@" << k << "\t" << metrics_.recall() << std::endl;
}

std::vector<std::pair<uint64_t, uint64_t>> Meter::getPositiveCounts(
    int32_t labelId) const {
  std::vector<std::pair<uint64_t, uint64_t>> positiveCounts;

  const auto& v = scoreVsTrue(labelId);
  uint64_t truePositives = 0;
  uint64_t falsePositives = 0;
  double lastScore = falseNegativeScore - 1.0;

  for (auto it = v.rbegin(); it != v.rend(); ++it) {
    double score = it->first;
    double gold = it->second;
    if (score < 0) { // only reachable recall
      break;
    }
    if (gold == 1.0) {
      truePositives++;
    } else {
      falsePositives++;
    }
    if (score == lastScore && positiveCounts.size()) { // squeeze tied scores
      positiveCounts.back() = {truePositives, falsePositives};
    } else {
      positiveCounts.emplace_back(truePositives, falsePositives);
    }
    lastScore = score;
  }

  return positiveCounts;
}

double Meter::precisionAtRecall(double recallQuery) const {
  return precisionAtRecall(kAllLabels, recallQuery);
}

double Meter::precisionAtRecall(int32_t labelId, double recallQuery) const {
  const auto& precisionRecall = precisionRecallCurve(labelId);
  double bestPrecision = 0.0;
  std::for_each(
      precisionRecall.begin(),
      precisionRecall.end(),
      [&bestPrecision, recallQuery](const std::pair<double, double>& element) {
        if (element.second >= recallQuery) {
          bestPrecision = std::max(bestPrecision, element.first);
        };
      });
  return bestPrecision;
}

double Meter::recallAtPrecision(double precisionQuery) const {
  return recallAtPrecision(kAllLabels, precisionQuery);
}

double Meter::recallAtPrecision(int32_t labelId, double precisionQuery) const {
  const auto& precisionRecall = precisionRecallCurve(labelId);
  double bestRecall = 0.0;
  std::for_each(
      precisionRecall.begin(),
      precisionRecall.end(),
      [&bestRecall, precisionQuery](const std::pair<double, double>& element) {
        if (element.first >= precisionQuery) {
          bestRecall = std::max(bestRecall, element.second);
        };
      });
  return bestRecall;
}

std::vector<std::pair<double, double>> Meter::precisionRecallCurve() const {
  return precisionRecallCurve(kAllLabels);
}

std::vector<std::pair<double, double>> Meter::precisionRecallCurve(
    int32_t labelId) const {
  std::vector<std::pair<double, double>> precisionRecallCurve;
  const auto& positiveCounts = getPositiveCounts(labelId);
  if (positiveCounts.empty()) {
    return precisionRecallCurve;
  }

  uint64_t golds =
      (labelId == kAllLabels) ? metrics_.gold : labelMetrics_.at(labelId).gold;

  auto fullRecall = std::lower_bound(
      positiveCounts.begin(),
      positiveCounts.end(),
      golds,
      utils::compareFirstLess);

  if (fullRecall != positiveCounts.end()) {
    fullRecall = std::next(fullRecall);
  }

  for (auto it = positiveCounts.begin(); it != fullRecall; it++) {
    double precision = 0.0;
    double truePositives = it->first;
    double falsePositives = it->second;
    if (truePositives + falsePositives != 0.0) {
      precision = truePositives / (truePositives + falsePositives);
    }
    double recall = golds != 0 ? (truePositives / double(golds))
                               : std::numeric_limits<double>::quiet_NaN();
    precisionRecallCurve.emplace_back(precision, recall);
  }
  precisionRecallCurve.emplace_back(1.0, 0.0);

  return precisionRecallCurve;
}

std::vector<std::pair<real, real>> Meter::scoreVsTrue(int32_t labelId) const {
  std::vector<std::pair<real, real>> ret;
  if (labelId == kAllLabels) {
    for (const auto& k : labelMetrics_) {
      auto& labelScoreVsTrue = labelMetrics_.at(k.first).scoreVsTrue;
      ret.insert(ret.end(), labelScoreVsTrue.begin(), labelScoreVsTrue.end());
    }
  } else {
    if (labelMetrics_.count(labelId)) {
      ret = labelMetrics_.at(labelId).scoreVsTrue;
    }
  }
  sort(ret.begin(), ret.end());

  return ret;
}

} // namespace fasttext
<commit_msg>fix test-label bug<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "meter.h"
#include "utils.h"

#include <algorithm>
#include <cmath>
#include <iomanip>
#include <limits>

namespace fasttext {

constexpr int32_t kAllLabels = -1;
constexpr real falseNegativeScore = -1.0;

void Meter::log(
    const std::vector<int32_t>& labels,
    const Predictions& predictions) {
  nexamples_++;
  metrics_.gold += labels.size();
  metrics_.predicted += predictions.size();

  for (const auto& prediction : predictions) {
    labelMetrics_[prediction.second].predicted++;

    real score = std::min(std::exp(prediction.first), 1.0f);
    real gold = 0.0;
    if (utils::contains(labels, prediction.second)) {
      labelMetrics_[prediction.second].predictedGold++;
      metrics_.predictedGold++;
      gold = 1.0;
    }
    labelMetrics_[prediction.second].scoreVsTrue.emplace_back(score, gold);
  }

  for (const auto& label : labels) {
    labelMetrics_[label].gold++;
    if (falseNegativeLabels_) {
      if (!utils::containsSecond(predictions, label)) {
        labelMetrics_[label].scoreVsTrue.emplace_back(falseNegativeScore, 1.0);
      }
    }
  }
}

double Meter::precision(int32_t i) {
  return labelMetrics_[i].precision();
}

double Meter::recall(int32_t i) {
  return labelMetrics_[i].recall();
}

double Meter::f1Score(int32_t i) {
  return labelMetrics_[i].f1Score();
}

double Meter::precision() const {
  return metrics_.precision();
}

double Meter::recall() const {
  return metrics_.recall();
}

double Meter::f1Score() const {
  const double precision = this->precision();
  const double recall = this->recall();
  if (precision + recall != 0) {
    return 2 * precision * recall / (precision + recall);
  }
  return std::numeric_limits<double>::quiet_NaN();
}

void Meter::writeGeneralMetrics(std::ostream& out, int32_t k) const {
  out << "N"
      << "\t" << nexamples_ << std::endl;
  out << std::setprecision(3);
  out << "P@" << k << "\t" << metrics_.precision() << std::endl;
  out << "R@" << k << "\t" << metrics_.recall() << std::endl;
}

std::vector<std::pair<uint64_t, uint64_t>> Meter::getPositiveCounts(
    int32_t labelId) const {
  std::vector<std::pair<uint64_t, uint64_t>> positiveCounts;

  const auto& v = scoreVsTrue(labelId);
  uint64_t truePositives = 0;
  uint64_t falsePositives = 0;
  double lastScore = falseNegativeScore - 1.0;

  for (auto it = v.rbegin(); it != v.rend(); ++it) {
    double score = it->first;
    double gold = it->second;
    if (score < 0) { // only reachable recall
      break;
    }
    if (gold == 1.0) {
      truePositives++;
    } else {
      falsePositives++;
    }
    if (score == lastScore && positiveCounts.size()) { // squeeze tied scores
      positiveCounts.back() = {truePositives, falsePositives};
    } else {
      positiveCounts.emplace_back(truePositives, falsePositives);
    }
    lastScore = score;
  }

  return positiveCounts;
}

double Meter::precisionAtRecall(double recallQuery) const {
  return precisionAtRecall(kAllLabels, recallQuery);
}

double Meter::precisionAtRecall(int32_t labelId, double recallQuery) const {
  const auto& precisionRecall = precisionRecallCurve(labelId);
  double bestPrecision = 0.0;
  std::for_each(
      precisionRecall.begin(),
      precisionRecall.end(),
      [&bestPrecision, recallQuery](const std::pair<double, double>& element) {
        if (element.second >= recallQuery) {
          bestPrecision = std::max(bestPrecision, element.first);
        };
      });
  return bestPrecision;
}

double Meter::recallAtPrecision(double precisionQuery) const {
  return recallAtPrecision(kAllLabels, precisionQuery);
}

double Meter::recallAtPrecision(int32_t labelId, double precisionQuery) const {
  const auto& precisionRecall = precisionRecallCurve(labelId);
  double bestRecall = 0.0;
  std::for_each(
      precisionRecall.begin(),
      precisionRecall.end(),
      [&bestRecall, precisionQuery](const std::pair<double, double>& element) {
        if (element.first >= precisionQuery) {
          bestRecall = std::max(bestRecall, element.second);
        };
      });
  return bestRecall;
}

std::vector<std::pair<double, double>> Meter::precisionRecallCurve() const {
  return precisionRecallCurve(kAllLabels);
}

std::vector<std::pair<double, double>> Meter::precisionRecallCurve(
    int32_t labelId) const {
  std::vector<std::pair<double, double>> precisionRecallCurve;
  const auto& positiveCounts = getPositiveCounts(labelId);
  if (positiveCounts.empty()) {
    return precisionRecallCurve;
  }

  uint64_t golds =
      (labelId == kAllLabels) ? metrics_.gold : labelMetrics_.at(labelId).gold;

  auto fullRecall = std::lower_bound(
      positiveCounts.begin(),
      positiveCounts.end(),
      golds,
      utils::compareFirstLess);

  if (fullRecall != positiveCounts.end()) {
    fullRecall = std::next(fullRecall);
  }

  for (auto it = positiveCounts.begin(); it != fullRecall; it++) {
    double precision = 0.0;
    double truePositives = it->first;
    double falsePositives = it->second;
    if (truePositives + falsePositives != 0.0) {
      precision = truePositives / (truePositives + falsePositives);
    }
    double recall = golds != 0 ? (truePositives / double(golds))
                               : std::numeric_limits<double>::quiet_NaN();
    precisionRecallCurve.emplace_back(precision, recall);
  }
  precisionRecallCurve.emplace_back(1.0, 0.0);

  return precisionRecallCurve;
}

std::vector<std::pair<real, real>> Meter::scoreVsTrue(int32_t labelId) const {
  std::vector<std::pair<real, real>> ret;
  if (labelId == kAllLabels) {
    for (const auto& k : labelMetrics_) {
      auto& labelScoreVsTrue = labelMetrics_.at(k.first).scoreVsTrue;
      ret.insert(ret.end(), labelScoreVsTrue.begin(), labelScoreVsTrue.end());
    }
  } else {
    if (labelMetrics_.count(labelId)) {
      ret = labelMetrics_.at(labelId).scoreVsTrue;
    }
  }
  sort(ret.begin(), ret.end());

  return ret;
}

} // namespace fasttext
<|endoftext|>


<commit_before>#ifndef ITER_DROPWHILE_H_
#define ITER_DROPWHILE_H_

#include "filter.hpp"
#include "internal/iterator_wrapper.hpp"
#include "internal/iterbase.hpp"

#include <iterator>
#include <utility>

namespace iter {
  namespace impl {
    template <typename FilterFunc, typename Container>
    class Dropper;

    using DropWhileFn = IterToolFnOptionalBindFirst<Dropper, BoolTester>;
  }
  constexpr impl::DropWhileFn dropwhile{};
}

template <typename FilterFunc, typename Container>
class iter::impl::Dropper {
 private:
  Container container;
  FilterFunc filter_func;

  friend DropWhileFn;

  Dropper(FilterFunc in_filter_func, Container&& in_container)
      : container(std::forward<Container>(in_container)),
        filter_func(in_filter_func) {}

 public:
  Dropper(Dropper&&) = default;
  class Iterator : public std::iterator<std::input_iterator_tag,
                       iterator_traits_deref<Container>> {
   private:
    using Holder = DerefHolder<iterator_deref<Container>>;
    IteratorWrapper<Container> sub_iter;
    IteratorWrapper<Container> sub_end;
    Holder item;
    FilterFunc* filter_func;

    void inc_sub_iter() {
      ++this->sub_iter;
      if (this->sub_iter != this->sub_end) {
        this->item.reset(*this->sub_iter);
      }
    }

    // skip all values for which the predicate is true
    void skip_passes() {
      while (this->sub_iter != this->sub_end
             && (*this->filter_func)(this->item.get())) {
        this->inc_sub_iter();
      }
    }

   public:
    Iterator(IteratorWrapper<Container>&& iter,
        IteratorWrapper<Container>&& end, FilterFunc& in_filter_func)
        : sub_iter{std::move(iter)},
          sub_end{std::move(end)},
          filter_func(&in_filter_func) {
      if (this->sub_iter != this->sub_end) {
        this->item.reset(*this->sub_iter);
      }
      this->skip_passes();
    }

    typename Holder::reference operator*() {
      return this->item.get();
    }

    typename Holder::pointer operator->() {
      return this->item.get_ptr();
    }

    Iterator& operator++() {
      this->inc_sub_iter();
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(this->container), std::end(this->container),
        this->filter_func};
  }

  Iterator end() {
    return {std::end(this->container), std::end(this->container),
        this->filter_func};
  }
};

#endif
<commit_msg>trailing _ on data members<commit_after>#ifndef ITER_DROPWHILE_H_
#define ITER_DROPWHILE_H_

#include "filter.hpp"
#include "internal/iterator_wrapper.hpp"
#include "internal/iterbase.hpp"

#include <iterator>
#include <utility>

namespace iter {
  namespace impl {
    template <typename FilterFunc, typename Container>
    class Dropper;

    using DropWhileFn = IterToolFnOptionalBindFirst<Dropper, BoolTester>;
  }
  constexpr impl::DropWhileFn dropwhile{};
}

template <typename FilterFunc, typename Container>
class iter::impl::Dropper {
 private:
  Container container_;
  FilterFunc filter_func_;

  friend DropWhileFn;

  Dropper(FilterFunc filter_func, Container&& container)
      : container_(std::forward<Container>(container)),
        filter_func_(filter_func) {}

 public:
  Dropper(Dropper&&) = default;
  class Iterator : public std::iterator<std::input_iterator_tag,
                       iterator_traits_deref<Container>> {
   private:
    using Holder = DerefHolder<iterator_deref<Container>>;
    IteratorWrapper<Container> sub_iter_;
    IteratorWrapper<Container> sub_end_;
    Holder item_;
    FilterFunc* filter_func_;

    void inc_sub_iter() {
      ++sub_iter_;
      if (sub_iter_ != sub_end_) {
        item_.reset(*sub_iter_);
      }
    }

    // skip all values for which the predicate is true
    void skip_passes() {
      while (sub_iter_ != sub_end_ && (*filter_func_)(item_.get())) {
        inc_sub_iter();
      }
    }

   public:
    Iterator(IteratorWrapper<Container>&& sub_iter,
        IteratorWrapper<Container>&& sub_end, FilterFunc& filter_func)
        : sub_iter_{std::move(sub_iter)},
          sub_end_{std::move(sub_end)},
          filter_func_(&filter_func) {
      if (sub_iter_ != sub_end_) {
        item_.reset(*sub_iter_);
      }
      skip_passes();
    }

    typename Holder::reference operator*() {
      return item_.get();
    }

    typename Holder::pointer operator->() {
      return item_.get_ptr();
    }

    Iterator& operator++() {
      inc_sub_iter();
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return sub_iter_ != other.sub_iter_;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(container_), std::end(container_), filter_func_};
  }

  Iterator end() {
    return {std::end(container_), std::end(container_), filter_func_};
  }
};

#endif
<|endoftext|>


<commit_before>#ifndef SPATIAL_HPP_INCLUDED
#define SPATIAL_HPP_INCLUDED

#include "glm.hpp"

namespace gst
{
    class Spatial {
    public:
        Spatial();

        void translate(float distance, glm::vec3 axis);
        void translate_x(float distance);
        void translate_y(float distance);
        void translate_z(float distance);

        void rotate(float angle_deg, glm::vec3 axis);
        void rotate_x(float angle_deg);
        void rotate_y(float angle_deg);
        void rotate_z(float angle_deg);

        glm::vec3 position;
        glm::vec3 scale;
        glm::quat orientation;

        glm::mat4 local_transform;
        glm::mat4 world_transform;
    };
}

#endif
<commit_msg>add documentation to spatial<commit_after>#ifndef SPATIAL_HPP_INCLUDED
#define SPATIAL_HPP_INCLUDED

#include "glm.hpp"

namespace gst
{
    // The responsibility of this class is to describe a position and
    // orientation in Euclidean space.
    class Spatial {
    public:
        Spatial();

        // Translate distance on axis in current orientation.
        void translate(float distance, glm::vec3 axis);
        // Translate distance on x-axis in current orientation.
        void translate_x(float distance);
        // Translate distance on y-axis in current orientation.
        void translate_y(float distance);
        // Translate distance on z-axis in current orientation.
        void translate_z(float distance);

        // Rotate with specified number of degrees around specified axis.
        void rotate(float angle_deg, glm::vec3 axis);
        // Rotate with specified number of degrees around x-axis.
        void rotate_x(float angle_deg);
        // Rotate with specified number of degrees around y-axis.
        void rotate_y(float angle_deg);
        // Rotate with specified number of degrees around z-axis.
        void rotate_z(float angle_deg);

        glm::vec3 position;
        glm::vec3 scale;
        glm::quat orientation;

        glm::mat4 local_transform;
        glm::mat4 world_transform;
    };
}

#endif
<|endoftext|>


<commit_before>/** Implementation of string conversions.
 *
 * Copyright (c) 2008-2017, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#include "pqxx/compiler-internal.hxx"

#include <cmath>
#include <cstring>
#include <limits>
#include <locale>

#include "pqxx/except"
#include "pqxx/strconv"

using namespace pqxx::internal;

namespace
{

template<typename T> inline void set_to_Inf(T &t, int sign=1)
{
  T value = std::numeric_limits<T>::infinity();
  if (sign < 0) value = -value;
  t = value;
}

[[noreturn]] void report_overflow()
{
  throw pqxx::failure(
	"Could not convert string to integer: value out of range.");
}

/** Helper to check for underflow before multiplying a number by 10.
 *
 * Needed just so the compiler doesn't get to complain about an "if (n < 0)"
 * clause that's pointless for unsigned numbers.
 */
template<typename T, bool is_signed> struct underflow_check;

/* Specialization for signed types: check.
 */
template<typename T> struct underflow_check<T, true>
{
  static void check_before_adding_digit(T n)
  {
    const T ten(10);
    if (n < 0 && (std::numeric_limits<T>::min() / ten) > n) report_overflow();
  }
};

/* Specialization for unsigned types: no check needed becaue negative
 * numbers don't exist.
 */
template<typename T> struct underflow_check<T, false>
{
  static void check_before_adding_digit(T) {}
};

/// Return 10*n, or throw exception if it overflows.
template<typename T> T safe_multiply_by_ten(T n)
{
  using limits = std::numeric_limits<T>;
  const T ten(10);
  if (n > 0 && (limits::max() / n) < ten) report_overflow();
  underflow_check<T, limits::is_signed>::check_before_adding_digit(n);
  return T(n * ten);
}

/// Add a digit d to n, or throw exception if it overflows.
template<typename T> T safe_add_digit(T n, T d)
{
  assert((n >= 0 && d >= 0) || (n <=0 && d <= 0));
  if ((n > 0) && (n > (std::numeric_limits<T>::max() - d))) report_overflow();
  if ((n < 0) && (n < (std::numeric_limits<T>::min() - d))) report_overflow();
  return n + d;
}

/// For use in string parsing: add new numeric digit to intermediate value
template<typename L, typename R>
  inline L absorb_digit(L value, R digit)
{
  return L(safe_multiply_by_ten(value) + L(digit));
}

template<typename T> void from_string_signed(const char Str[], T &Obj)
{
  int i = 0;
  T result = 0;

  if (!isdigit(Str[i]))
  {
    if (Str[i] != '-')
      throw pqxx::failure(
        "Could not convert string to integer: '" + std::string(Str) + "'");

    for (++i; isdigit(Str[i]); ++i)
      result = absorb_digit(result, -digit_to_number(Str[i]));
  }
  else
  {
    for (; isdigit(Str[i]); ++i)
      result = absorb_digit(result, digit_to_number(Str[i]));
  }

  if (Str[i])
    throw pqxx::failure(
      "Unexpected text after integer: '" + std::string(Str) + "'");

  Obj = result;
}

template<typename T> void from_string_unsigned(const char Str[], T &Obj)
{
  int i = 0;
  T result = 0;

  if (!isdigit(Str[i]))
    throw pqxx::failure(
      "Could not convert string to unsigned integer: '" +
      std::string(Str) + "'");

  for (; isdigit(Str[i]); ++i)
    result = absorb_digit(result, digit_to_number(Str[i]));

  if (Str[i])
    throw pqxx::failure(
      "Unexpected text after integer: '" + std::string(Str) + "'");

  Obj = result;
}

bool valid_infinity_string(const char str[]) noexcept
{
  return
	strcmp("infinity", str) == 0 ||
	strcmp("Infinity", str) == 0 ||
	strcmp("INFINITY", str) == 0 ||
	strcmp("inf", str) == 0;
}

/// Wrapper for std::stringstream with C locale.
/** Some of our string conversions use the standard library.  But, they must
 * _not_ obey the system's locale settings, or a value like 1000.0 might end
 * up looking like "1.000,0".
 *
 * Initialising the stream (including locale and tweaked precision) seems to
 * be expensive though.  So, create thread-local instances which we re-use.
 * It's a lockless way of keeping global variables thread-safe, basically.
 *
 * The stream initialisation happens once per thread, in the constructor.
 * And that's why we need to wrap this in a class.  We can't just do it at the
 * call site, or we'd still be doing it for every call.
 */
template<typename T> class dumb_stringstream : public std::stringstream
{
public:
  dumb_stringstream() : std::stringstream()
  {
    this->imbue(std::locale::classic());

    // Kirit reports getting two more digits of precision than
    // numeric_limits::digits10 would give him, so we try not to make him lose
    // those last few bits.
    this->precision(std::numeric_limits<T>::digits10 + 2);
  }
};

/* These are hard.  Sacrifice performance of specialized, nonflexible,
 * non-localized code and lean on standard library.  Some special-case code
 * handles NaNs.
 */
template<typename T> inline void from_string_float(const char Str[], T &Obj)
{
  bool ok = false;
  T result;

  switch (Str[0])
  {
  case 'N':
  case 'n':
    // Accept "NaN," "nan," etc.
    ok = ((Str[1]=='A'||Str[1]=='a') && (Str[2]=='N'||Str[2]=='n') && !Str[3]);
    result = std::numeric_limits<T>::quiet_NaN();
    break;

  case 'I':
  case 'i':
    ok = valid_infinity_string(Str);
    set_to_Inf(result);
    break;

  default:
    if (Str[0] == '-' && valid_infinity_string(&Str[1]))
    {
      ok = true;
      set_to_Inf(result, -1);
    }
    else
    {
      thread_local dumb_stringstream<T> S;
      S.seekg(0);
      S.str(Str);
      ok = static_cast<bool>(S >> result);
    }
    break;
  }

  if (!ok)
    throw pqxx::failure(
      "Could not convert string to numeric value: '" +
      std::string(Str) + "'");

  Obj = result;
}

template<typename T> inline std::string to_string_unsigned(T Obj)
{
  if (!Obj) return "0";

  // Every byte of width on T adds somewhere between 3 and 4 digits to the
  // maximum length of our decimal string.
  char buf[4*sizeof(T)+1];

  char *p = &buf[sizeof(buf)];
  *--p = '\0';
  while (Obj > 0)
  {
    *--p = number_to_digit(int(Obj%10));
    Obj /= 10;
  }
  return p;
}

template<typename T> inline std::string to_string_fallback(T Obj)
{
  thread_local dumb_stringstream<T> S;
  S.str("");
  S << Obj;
  return S.str();
}

template<typename T> inline std::string to_string_float(T Obj)
{
  if (std::isnan(Obj)) return "nan";
  if (std::isinf(Obj)) return Obj > 0 ? "infinity" : "-infinity";
  return to_string_fallback(Obj);
}

template<typename T> inline std::string to_string_signed(T Obj)
{
  if (Obj < 0)
  {
    // Remember--the smallest negative number for a given two's-complement type
    // cannot be negated.
    const bool negatable = (Obj != std::numeric_limits<T>::min());
    if (negatable)
      return '-' + to_string_unsigned(-Obj);
    else
      return to_string_fallback(Obj);
  }

  return to_string_unsigned(Obj);
}

} // namespace

namespace pqxx
{

namespace internal
{
void throw_null_conversion(const std::string &type)
{
  throw conversion_error("Attempt to convert null to " + type);
}
} // namespace pqxx::internal

void string_traits<bool>::from_string(const char Str[], bool &Obj)
{
  bool OK, result=false;

  switch (Str[0])
  {
  case 0:
    result = false;
    OK = true;
    break;

  case 'f':
  case 'F':
    result = false;
    OK = !(
	Str[1] &&
	(strcmp(Str+1, "alse") != 0) &&
	(strcmp(Str+1, "ALSE") != 0));
    break;

  case '0':
    {
      int I;
      string_traits<int>::from_string(Str, I);
      result = (I != 0);
      OK = ((I == 0) || (I == 1));
    }
    break;

  case '1':
    result = true;
    OK = !Str[1];
    break;

  case 't':
  case 'T':
    result = true;
    OK = !(
	Str[1] &&
	(strcmp(Str+1, "rue") != 0) &&
	(strcmp(Str+1, "RUE") != 0));
    break;

  default:
    OK = false;
  }

  if (!OK)
    throw argument_error(
      "Failed conversion to bool: '" + std::string(Str) + "'");

  Obj = result;
}

std::string string_traits<bool>::to_string(bool Obj)
{
  return Obj ? "true" : "false";
}

void string_traits<short>::from_string(const char Str[], short &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<short>::to_string(short Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned short>::from_string(
	const char Str[],
	unsigned short &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned short>::to_string(unsigned short Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<int>::from_string(const char Str[], int &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<int>::to_string(int Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned int>::from_string(
	const char Str[],
	unsigned int &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned int>::to_string(unsigned int Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<long>::from_string(const char Str[], long &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<long>::to_string(long Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned long>::from_string(
	const char Str[],
	unsigned long &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned long>::to_string(unsigned long Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<long long>::from_string(const char Str[], long long &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<long long>::to_string(long long Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned long long>::from_string(
	const char Str[],
	unsigned long long &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned long long>::to_string(
        unsigned long long Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<float>::from_string(const char Str[], float &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<float>::to_string(float Obj)
{
  return to_string_float(Obj);
}

void string_traits<double>::from_string(const char Str[], double &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<double>::to_string(double Obj)
{
  return to_string_float(Obj);
}

void string_traits<long double>::from_string(const char Str[], long double &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<long double>::to_string(long double Obj)
{
  return to_string_float(Obj);
}

} // namespace pqxx
<commit_msg>Clear stream flags before string conversion.<commit_after>/** Implementation of string conversions.
 *
 * Copyright (c) 2008-2017, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#include "pqxx/compiler-internal.hxx"

#include <cmath>
#include <cstring>
#include <limits>
#include <locale>

#include "pqxx/except"
#include "pqxx/strconv"

using namespace pqxx::internal;

namespace
{

template<typename T> inline void set_to_Inf(T &t, int sign=1)
{
  T value = std::numeric_limits<T>::infinity();
  if (sign < 0) value = -value;
  t = value;
}

[[noreturn]] void report_overflow()
{
  throw pqxx::failure(
	"Could not convert string to integer: value out of range.");
}

/** Helper to check for underflow before multiplying a number by 10.
 *
 * Needed just so the compiler doesn't get to complain about an "if (n < 0)"
 * clause that's pointless for unsigned numbers.
 */
template<typename T, bool is_signed> struct underflow_check;

/* Specialization for signed types: check.
 */
template<typename T> struct underflow_check<T, true>
{
  static void check_before_adding_digit(T n)
  {
    const T ten(10);
    if (n < 0 && (std::numeric_limits<T>::min() / ten) > n) report_overflow();
  }
};

/* Specialization for unsigned types: no check needed becaue negative
 * numbers don't exist.
 */
template<typename T> struct underflow_check<T, false>
{
  static void check_before_adding_digit(T) {}
};

/// Return 10*n, or throw exception if it overflows.
template<typename T> T safe_multiply_by_ten(T n)
{
  using limits = std::numeric_limits<T>;
  const T ten(10);
  if (n > 0 && (limits::max() / n) < ten) report_overflow();
  underflow_check<T, limits::is_signed>::check_before_adding_digit(n);
  return T(n * ten);
}

/// Add a digit d to n, or throw exception if it overflows.
template<typename T> T safe_add_digit(T n, T d)
{
  assert((n >= 0 && d >= 0) || (n <=0 && d <= 0));
  if ((n > 0) && (n > (std::numeric_limits<T>::max() - d))) report_overflow();
  if ((n < 0) && (n < (std::numeric_limits<T>::min() - d))) report_overflow();
  return n + d;
}

/// For use in string parsing: add new numeric digit to intermediate value
template<typename L, typename R>
  inline L absorb_digit(L value, R digit)
{
  return L(safe_multiply_by_ten(value) + L(digit));
}

template<typename T> void from_string_signed(const char Str[], T &Obj)
{
  int i = 0;
  T result = 0;

  if (!isdigit(Str[i]))
  {
    if (Str[i] != '-')
      throw pqxx::failure(
        "Could not convert string to integer: '" + std::string(Str) + "'");

    for (++i; isdigit(Str[i]); ++i)
      result = absorb_digit(result, -digit_to_number(Str[i]));
  }
  else
  {
    for (; isdigit(Str[i]); ++i)
      result = absorb_digit(result, digit_to_number(Str[i]));
  }

  if (Str[i])
    throw pqxx::failure(
      "Unexpected text after integer: '" + std::string(Str) + "'");

  Obj = result;
}

template<typename T> void from_string_unsigned(const char Str[], T &Obj)
{
  int i = 0;
  T result = 0;

  if (!isdigit(Str[i]))
    throw pqxx::failure(
      "Could not convert string to unsigned integer: '" +
      std::string(Str) + "'");

  for (; isdigit(Str[i]); ++i)
    result = absorb_digit(result, digit_to_number(Str[i]));

  if (Str[i])
    throw pqxx::failure(
      "Unexpected text after integer: '" + std::string(Str) + "'");

  Obj = result;
}

bool valid_infinity_string(const char str[]) noexcept
{
  return
	strcmp("infinity", str) == 0 ||
	strcmp("Infinity", str) == 0 ||
	strcmp("INFINITY", str) == 0 ||
	strcmp("inf", str) == 0;
}

/// Wrapper for std::stringstream with C locale.
/** Some of our string conversions use the standard library.  But, they must
 * _not_ obey the system's locale settings, or a value like 1000.0 might end
 * up looking like "1.000,0".
 *
 * Initialising the stream (including locale and tweaked precision) seems to
 * be expensive though.  So, create thread-local instances which we re-use.
 * It's a lockless way of keeping global variables thread-safe, basically.
 *
 * The stream initialisation happens once per thread, in the constructor.
 * And that's why we need to wrap this in a class.  We can't just do it at the
 * call site, or we'd still be doing it for every call.
 */
template<typename T> class dumb_stringstream : public std::stringstream
{
public:
  dumb_stringstream() : std::stringstream()
  {
    this->imbue(std::locale::classic());

    // Kirit reports getting two more digits of precision than
    // numeric_limits::digits10 would give him, so we try not to make him lose
    // those last few bits.
    this->precision(std::numeric_limits<T>::digits10 + 2);
  }
};

/* These are hard.  Sacrifice performance of specialized, nonflexible,
 * non-localized code and lean on standard library.  Some special-case code
 * handles NaNs.
 */
template<typename T> inline void from_string_float(const char Str[], T &Obj)
{
  bool ok = false;
  T result;

  switch (Str[0])
  {
  case 'N':
  case 'n':
    // Accept "NaN," "nan," etc.
    ok = ((Str[1]=='A'||Str[1]=='a') && (Str[2]=='N'||Str[2]=='n') && !Str[3]);
    result = std::numeric_limits<T>::quiet_NaN();
    break;

  case 'I':
  case 'i':
    ok = valid_infinity_string(Str);
    set_to_Inf(result);
    break;

  default:
    if (Str[0] == '-' && valid_infinity_string(&Str[1]))
    {
      ok = true;
      set_to_Inf(result, -1);
    }
    else
    {
      thread_local dumb_stringstream<T> S;
      S.clear();
      S.seekg(0);
      S.str(Str);
      ok = static_cast<bool>(S >> result);
    }
    break;
  }

  if (!ok)
    throw pqxx::failure(
      "Could not convert string to numeric value: '" +
      std::string(Str) + "'");

  Obj = result;
}

template<typename T> inline std::string to_string_unsigned(T Obj)
{
  if (!Obj) return "0";

  // Every byte of width on T adds somewhere between 3 and 4 digits to the
  // maximum length of our decimal string.
  char buf[4*sizeof(T)+1];

  char *p = &buf[sizeof(buf)];
  *--p = '\0';
  while (Obj > 0)
  {
    *--p = number_to_digit(int(Obj%10));
    Obj /= 10;
  }
  return p;
}

template<typename T> inline std::string to_string_fallback(T Obj)
{
  thread_local dumb_stringstream<T> S;
  S.str("");
  S << Obj;
  return S.str();
}

template<typename T> inline std::string to_string_float(T Obj)
{
  if (std::isnan(Obj)) return "nan";
  if (std::isinf(Obj)) return Obj > 0 ? "infinity" : "-infinity";
  return to_string_fallback(Obj);
}

template<typename T> inline std::string to_string_signed(T Obj)
{
  if (Obj < 0)
  {
    // Remember--the smallest negative number for a given two's-complement type
    // cannot be negated.
    const bool negatable = (Obj != std::numeric_limits<T>::min());
    if (negatable)
      return '-' + to_string_unsigned(-Obj);
    else
      return to_string_fallback(Obj);
  }

  return to_string_unsigned(Obj);
}

} // namespace

namespace pqxx
{

namespace internal
{
void throw_null_conversion(const std::string &type)
{
  throw conversion_error("Attempt to convert null to " + type);
}
} // namespace pqxx::internal

void string_traits<bool>::from_string(const char Str[], bool &Obj)
{
  bool OK, result=false;

  switch (Str[0])
  {
  case 0:
    result = false;
    OK = true;
    break;

  case 'f':
  case 'F':
    result = false;
    OK = !(
	Str[1] &&
	(strcmp(Str+1, "alse") != 0) &&
	(strcmp(Str+1, "ALSE") != 0));
    break;

  case '0':
    {
      int I;
      string_traits<int>::from_string(Str, I);
      result = (I != 0);
      OK = ((I == 0) || (I == 1));
    }
    break;

  case '1':
    result = true;
    OK = !Str[1];
    break;

  case 't':
  case 'T':
    result = true;
    OK = !(
	Str[1] &&
	(strcmp(Str+1, "rue") != 0) &&
	(strcmp(Str+1, "RUE") != 0));
    break;

  default:
    OK = false;
  }

  if (!OK)
    throw argument_error(
      "Failed conversion to bool: '" + std::string(Str) + "'");

  Obj = result;
}

std::string string_traits<bool>::to_string(bool Obj)
{
  return Obj ? "true" : "false";
}

void string_traits<short>::from_string(const char Str[], short &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<short>::to_string(short Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned short>::from_string(
	const char Str[],
	unsigned short &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned short>::to_string(unsigned short Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<int>::from_string(const char Str[], int &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<int>::to_string(int Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned int>::from_string(
	const char Str[],
	unsigned int &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned int>::to_string(unsigned int Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<long>::from_string(const char Str[], long &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<long>::to_string(long Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned long>::from_string(
	const char Str[],
	unsigned long &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned long>::to_string(unsigned long Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<long long>::from_string(const char Str[], long long &Obj)
{
  from_string_signed(Str, Obj);
}

std::string string_traits<long long>::to_string(long long Obj)
{
  return to_string_signed(Obj);
}

void string_traits<unsigned long long>::from_string(
	const char Str[],
	unsigned long long &Obj)
{
  from_string_unsigned(Str, Obj);
}

std::string string_traits<unsigned long long>::to_string(
        unsigned long long Obj)
{
  return to_string_unsigned(Obj);
}

void string_traits<float>::from_string(const char Str[], float &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<float>::to_string(float Obj)
{
  return to_string_float(Obj);
}

void string_traits<double>::from_string(const char Str[], double &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<double>::to_string(double Obj)
{
  return to_string_float(Obj);
}

void string_traits<long double>::from_string(const char Str[], long double &Obj)
{
  from_string_float(Str, Obj);
}

std::string string_traits<long double>::to_string(long double Obj)
{
  return to_string_float(Obj);
}

} // namespace pqxx
<|endoftext|>


<commit_before>/******************************************************************************************[Main.C]
Copyright (c) 2007, Niklas Sorensson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/

#include "utils/Options.h"
#include "utils/System.h"
#include "simp/SimpSolver.h"
#include "circ/Circ.h"
#include "circ/Clausify.h"
#include "circ/Aiger.h"
#include "circ/DagShrink.h"
#include "circ/CombSweep.h"

#include <cstdio>
#include <cstring>
#include <errno.h>
#include <signal.h>

using namespace Minisat;

//=================================================================================================

static
void printStats(Solver& solver)
{
    double cpu_time = cpuTime();
    double mem_used = memUsed();
    printf("restarts              : %"PRIu64"\n", solver.starts);
    printf("conflicts             : %-12"PRIu64"   (%.0f /sec)\n", solver.conflicts   , solver.conflicts   /cpu_time);
    printf("decisions             : %-12"PRIu64"   (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions   /cpu_time);
    printf("propagations          : %-12"PRIu64"   (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
    printf("conflict literals     : %-12"PRIu64"   (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
    if (mem_used != 0) printf("Memory used           : %.2f MB\n", mem_used);
    printf("CPU time              : %g s\n", cpu_time);
}

SimpSolver* solver;
static void SIGINT_handler(int signum) {
    printf("\n"); printf("*** INTERRUPTED ***\n");
    printStats(*solver);
    printf("\n"); printf("*** INTERRUPTED ***\n");
    exit(1); }

//=================================================================================================
// Main:

int main(int argc, char** argv)
{
    setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n  where input is in plain or gzipped binary AIGER.\n");
    printf("Using MiniSat 2.0 beta\n");

#if defined(__linux__)
    fpu_control_t oldcw, newcw;
    _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
    printf("WARNING: for repeatability, setting FPU to use double precision\n");
#endif

    // Extra options:
    //
    BoolOption   pre            ("MAIN", "pre",    "Completely turn on/off any preprocessing.", true);
    BoolOption   clausify_naive ("MAIN", "clausify-naive", "Use naive clausification", false);
    StringOption aiger          ("MAIN", "aiger",  "If given, stop after preprocessing AIG and write the result to this file.");
    StringOption dimacs         ("MAIN", "dimacs", "If given, stop after producing CNF and write the result to this file.");
    IntOption    dash_iters     ("MAIN", "dash-iters", "Number of DAG Aware Rewriting iterations.", 5);
    BoolOption   split_output   ("MAIN", "split-output", "Split the topmost output conjunctions into multiple outputs.", true);

    parseOptions(argc, argv, true);

    SimpSolver S;
    double     initial_time = cpuTime();

    if (!pre) S.eliminate(true);

    solver = &S;
    signal(SIGINT,SIGINT_handler);
    signal(SIGHUP,SIGINT_handler);

    vec<Var> input_vars;

    if (argc < 2 || argc > 3)
        printUsageAndExit(argc, argv);
    else {
        printf("============================[ Problem Statistics ]=============================\n");
        printf("|                                                                             |\n");

        Circ  c;
        Box   b;
        Flops flp;
        readAiger(argv[1], c, b, flp);

        if (flp.size() > 0)
            fprintf(stderr, "ERROR! Sequential circuits not supported!\n"), exit(1);

        //if (c.outputs.size() != 1)
        //    fprintf(stderr, "ERROR! Exactly 1 output expected, found %d!\n", c.outputs.size()), exit(1);
        if (split_output)
            splitOutputs(c, b, flp);

        printf("|  Number of inputs:     %12d                                         |\n", c.nInps());
        printf("|  Number of outputs:    %12d                                         |\n", b.outs.size());
        printf("|  Number of gates:      %12d                                         |\n", c.nGates());

        double parsed_time = cpuTime();
        printf("|  Parse time:           %12.2f s                                       |\n", parsed_time - initial_time);

        //dagShrinkIter(c, b, flp, (int)dash_iters);
        dagShrinkIter(c, b, flp, 0.005);

        double _time = cpuTime();

        printf("|  Parse time:           %12.2f s                                       |\n", parsed_time - initial_time);

#if 0
        Eqs cand; makeUnitClass(c, cand);

        GSet props;
        for (int i  = 0; i < b.outs.size(); i++)
            props.insert(gate(b.outs[i]));

        for (int k = 0; k < cand.size(); k++){
            int i,j;
            for (i = j = 0; i < cand[k].size(); i++)
                if (!props.has(gate(cand[k][i])))
                    cand[k][j++] = cand[k][i];
            cand[k].shrink(i - j);
        }

        Eqs proven;
        Solver             sweep_s;
        sweep_s.verbosity = 0;
        sweep_s.rnd_pol = true;
        Clausifyer<Solver, false, false> sweep_cl(c, sweep_s);
        combEqSweep(c, sweep_cl, sweep_s, cand, proven);

        GMap<Sig> subst;
        makeSubstMap(proven, subst);

        Circ      tmp_circ;
        GMap<Sig> tmp_m;
        copyCircWithSubst(c, tmp_circ, subst, tmp_m);
        map(tmp_m, b);
        map(tmp_m, flp);
        tmp_circ.moveTo(c);

        printf("|  Number of inputs:     %12d                                         |\n", c.nInps());
        printf("|  Number of outputs:    %12d                                         |\n", b.outs.size());
        printf("|  Number of gates:      %12d                                         |\n", c.nGates());

        dagShrinkIter(c, b, flp, 10);

#endif

        // void circInfo (      Circ& c, Gate g, GSet& reachable, int& n_ands, int& n_xors, int& n_muxes, int& tot_ands);
        // {
        //     GSet r; int n_ands = 0, n_xors = 0, n_muxs = 0, tot_ands = 0;
        //
        //     for (int i = 0; i < c.outputs.size(); i++)
        //         circInfo(c.circ, gate(c.outputs[i]), r, n_ands, n_xors, n_muxs, tot_ands);
        //     fprintf(stderr, " >> ANDS = %d, XORS = %d, MUXES = %d, TOT = %d\n", n_ands, n_xors, n_muxs, tot_ands);
        // }

        if (aiger != NULL){
            printf("==============================[ Writing AIGER ]================================\n");
            writeAiger(aiger, c, b, flp);
            exit(0);
        }

        vec<Lit> unit;
        if (clausify_naive){
            NaiveClausifyer<SimpSolver> cl(c, S);
            for (int i = 0; i < b.outs.size(); i++){
                unit.clear();
                unit.push(cl.clausify(b.outs[i]));
                assert(S.okay());
                assert(S.value(unit.last()) == l_Undef);
                S.addClause(unit);
            }

            for (int i = 0; i < b.inps.size(); i++)
                input_vars.push(cl.clausify(b.inps[i]));

        }else {
            Clausifyer<SimpSolver> cl(c, S);
            //cl.prepare();

            for (int i = 0; i < b.outs.size(); i++)
                cl.assume(b.outs[i]);

            for (int i = 0; i < b.inps.size(); i++){
                Lit x = cl.clausify(b.inps[i]);
                assert(!sign(x));
                input_vars.push(var(x));
            }
        }

        printf("|  Number of variables:  %12d                                         |\n", S.nVars());
        printf("|  Number of clauses:    %12d                                         |\n", S.nClauses());

        double clausify_time = cpuTime();
        printf("|  Clausify time:        %12.2f s                                       |\n", clausify_time - parsed_time);
    }

    // Freeze input vars:
    //for (int i = 0; i < input_vars.size(); i++)
    //    S.setFrozen(input_vars[i], true);

    if (pre){
        double simplified_time_before = cpuTime();
        S.eliminate(true);
        printf("|  Simplification time:  %12.2f s                                       |\n", cpuTime() - simplified_time_before);
    }
    printf("|                                                                             |\n");

    FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;

    if (!S.okay()){
        if (res != NULL) fprintf(res, "0\n"), fclose(res);
        printf("===============================================================================\n");
        printf("Solved by simplification\n");
        printStats(S);
        printf("\n");
        printf("UNSATISFIABLE\n");
        exit(20);
    }

    if (dimacs){
        printf("==============================[ Writing DIMACS ]===============================\n");
        S.toDimacs(dimacs);
        printStats(S);
        exit(0);
    }else{
        bool ret = S.solve();
        printStats(S);
        printf("\n");
        printf(ret ? "SATISFIABLE\n" : "UNSATISFIABLE\n");
        if (res != NULL){
            if (ret){
                fprintf(res, "1\n");
                for (int i = 0; i < input_vars.size(); i++){
                    Var inp = input_vars[i];
                    if (S.model[inp] == l_Undef)
                        fprintf(res, "x");
                    else if (S.model[inp] == l_True)
                        fprintf(res, "1");
                    else
                        fprintf(res, "0");
                }
                fprintf(res, "\n");
            }else
                fprintf(res, "0\n");
            fclose(res);
        }
#ifdef NDEBUG
        exit(ret ? 10 : 20);     // (faster than "return", which will invoke the destructor for 'Solver')
#endif
    }
}
<commit_msg>Remove accidentally introduced printout.<commit_after>/******************************************************************************************[Main.C]
Copyright (c) 2007, Niklas Sorensson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/

#include "utils/Options.h"
#include "utils/System.h"
#include "simp/SimpSolver.h"
#include "circ/Circ.h"
#include "circ/Clausify.h"
#include "circ/Aiger.h"
#include "circ/DagShrink.h"
#include "circ/CombSweep.h"

#include <cstdio>
#include <cstring>
#include <errno.h>
#include <signal.h>

using namespace Minisat;

//=================================================================================================

static
void printStats(Solver& solver)
{
    double cpu_time = cpuTime();
    double mem_used = memUsed();
    printf("restarts              : %"PRIu64"\n", solver.starts);
    printf("conflicts             : %-12"PRIu64"   (%.0f /sec)\n", solver.conflicts   , solver.conflicts   /cpu_time);
    printf("decisions             : %-12"PRIu64"   (%4.2f %% random) (%.0f /sec)\n", solver.decisions, (float)solver.rnd_decisions*100 / (float)solver.decisions, solver.decisions   /cpu_time);
    printf("propagations          : %-12"PRIu64"   (%.0f /sec)\n", solver.propagations, solver.propagations/cpu_time);
    printf("conflict literals     : %-12"PRIu64"   (%4.2f %% deleted)\n", solver.tot_literals, (solver.max_literals - solver.tot_literals)*100 / (double)solver.max_literals);
    if (mem_used != 0) printf("Memory used           : %.2f MB\n", mem_used);
    printf("CPU time              : %g s\n", cpu_time);
}

SimpSolver* solver;
static void SIGINT_handler(int signum) {
    printf("\n"); printf("*** INTERRUPTED ***\n");
    printStats(*solver);
    printf("\n"); printf("*** INTERRUPTED ***\n");
    exit(1); }

//=================================================================================================
// Main:

int main(int argc, char** argv)
{
    setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n  where input is in plain or gzipped binary AIGER.\n");
    printf("Using MiniSat 2.0 beta\n");

#if defined(__linux__)
    fpu_control_t oldcw, newcw;
    _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
    printf("WARNING: for repeatability, setting FPU to use double precision\n");
#endif

    // Extra options:
    //
    BoolOption   pre            ("MAIN", "pre",    "Completely turn on/off any preprocessing.", true);
    BoolOption   clausify_naive ("MAIN", "clausify-naive", "Use naive clausification", false);
    StringOption aiger          ("MAIN", "aiger",  "If given, stop after preprocessing AIG and write the result to this file.");
    StringOption dimacs         ("MAIN", "dimacs", "If given, stop after producing CNF and write the result to this file.");
    IntOption    dash_iters     ("MAIN", "dash-iters", "Number of DAG Aware Rewriting iterations.", 5);
    BoolOption   split_output   ("MAIN", "split-output", "Split the topmost output conjunctions into multiple outputs.", true);

    parseOptions(argc, argv, true);

    SimpSolver S;
    double     initial_time = cpuTime();

    if (!pre) S.eliminate(true);

    solver = &S;
    signal(SIGINT,SIGINT_handler);
    signal(SIGHUP,SIGINT_handler);

    vec<Var> input_vars;

    if (argc < 2 || argc > 3)
        printUsageAndExit(argc, argv);
    else {
        printf("============================[ Problem Statistics ]=============================\n");
        printf("|                                                                             |\n");

        Circ  c;
        Box   b;
        Flops flp;
        readAiger(argv[1], c, b, flp);

        if (flp.size() > 0)
            fprintf(stderr, "ERROR! Sequential circuits not supported!\n"), exit(1);

        //if (c.outputs.size() != 1)
        //    fprintf(stderr, "ERROR! Exactly 1 output expected, found %d!\n", c.outputs.size()), exit(1);
        if (split_output)
            splitOutputs(c, b, flp);

        printf("|  Number of inputs:     %12d                                         |\n", c.nInps());
        printf("|  Number of outputs:    %12d                                         |\n", b.outs.size());
        printf("|  Number of gates:      %12d                                         |\n", c.nGates());

        double parsed_time = cpuTime();
        printf("|  Parse time:           %12.2f s                                       |\n", parsed_time - initial_time);

        //dagShrinkIter(c, b, flp, (int)dash_iters);
        dagShrinkIter(c, b, flp, 0.005);

#if 0
        Eqs cand; makeUnitClass(c, cand);

        GSet props;
        for (int i  = 0; i < b.outs.size(); i++)
            props.insert(gate(b.outs[i]));

        for (int k = 0; k < cand.size(); k++){
            int i,j;
            for (i = j = 0; i < cand[k].size(); i++)
                if (!props.has(gate(cand[k][i])))
                    cand[k][j++] = cand[k][i];
            cand[k].shrink(i - j);
        }

        Eqs proven;
        Solver             sweep_s;
        sweep_s.verbosity = 0;
        sweep_s.rnd_pol = true;
        Clausifyer<Solver, false, false> sweep_cl(c, sweep_s);
        combEqSweep(c, sweep_cl, sweep_s, cand, proven);

        GMap<Sig> subst;
        makeSubstMap(proven, subst);

        Circ      tmp_circ;
        GMap<Sig> tmp_m;
        copyCircWithSubst(c, tmp_circ, subst, tmp_m);
        map(tmp_m, b);
        map(tmp_m, flp);
        tmp_circ.moveTo(c);

        printf("|  Number of inputs:     %12d                                         |\n", c.nInps());
        printf("|  Number of outputs:    %12d                                         |\n", b.outs.size());
        printf("|  Number of gates:      %12d                                         |\n", c.nGates());

        dagShrinkIter(c, b, flp, 10);

#endif

        // void circInfo (      Circ& c, Gate g, GSet& reachable, int& n_ands, int& n_xors, int& n_muxes, int& tot_ands);
        // {
        //     GSet r; int n_ands = 0, n_xors = 0, n_muxs = 0, tot_ands = 0;
        //
        //     for (int i = 0; i < c.outputs.size(); i++)
        //         circInfo(c.circ, gate(c.outputs[i]), r, n_ands, n_xors, n_muxs, tot_ands);
        //     fprintf(stderr, " >> ANDS = %d, XORS = %d, MUXES = %d, TOT = %d\n", n_ands, n_xors, n_muxs, tot_ands);
        // }

        if (aiger != NULL){
            printf("==============================[ Writing AIGER ]================================\n");
            writeAiger(aiger, c, b, flp);
            exit(0);
        }

        vec<Lit> unit;
        if (clausify_naive){
            NaiveClausifyer<SimpSolver> cl(c, S);
            for (int i = 0; i < b.outs.size(); i++){
                unit.clear();
                unit.push(cl.clausify(b.outs[i]));
                assert(S.okay());
                assert(S.value(unit.last()) == l_Undef);
                S.addClause(unit);
            }

            for (int i = 0; i < b.inps.size(); i++)
                input_vars.push(cl.clausify(b.inps[i]));

        }else {
            Clausifyer<SimpSolver> cl(c, S);
            //cl.prepare();

            for (int i = 0; i < b.outs.size(); i++)
                cl.assume(b.outs[i]);

            for (int i = 0; i < b.inps.size(); i++){
                Lit x = cl.clausify(b.inps[i]);
                assert(!sign(x));
                input_vars.push(var(x));
            }
        }

        printf("|  Number of variables:  %12d                                         |\n", S.nVars());
        printf("|  Number of clauses:    %12d                                         |\n", S.nClauses());

        double clausify_time = cpuTime();
        printf("|  Clausify time:        %12.2f s                                       |\n", clausify_time - parsed_time);
    }

    // Freeze input vars:
    //for (int i = 0; i < input_vars.size(); i++)
    //    S.setFrozen(input_vars[i], true);

    if (pre){
        double simplified_time_before = cpuTime();
        S.eliminate(true);
        printf("|  Simplification time:  %12.2f s                                       |\n", cpuTime() - simplified_time_before);
    }
    printf("|                                                                             |\n");

    FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;

    if (!S.okay()){
        if (res != NULL) fprintf(res, "0\n"), fclose(res);
        printf("===============================================================================\n");
        printf("Solved by simplification\n");
        printStats(S);
        printf("\n");
        printf("UNSATISFIABLE\n");
        exit(20);
    }

    if (dimacs){
        printf("==============================[ Writing DIMACS ]===============================\n");
        S.toDimacs(dimacs);
        printStats(S);
        exit(0);
    }else{
        bool ret = S.solve();
        printStats(S);
        printf("\n");
        printf(ret ? "SATISFIABLE\n" : "UNSATISFIABLE\n");
        if (res != NULL){
            if (ret){
                fprintf(res, "1\n");
                for (int i = 0; i < input_vars.size(); i++){
                    Var inp = input_vars[i];
                    if (S.model[inp] == l_Undef)
                        fprintf(res, "x");
                    else if (S.model[inp] == l_True)
                        fprintf(res, "1");
                    else
                        fprintf(res, "0");
                }
                fprintf(res, "\n");
            }else
                fprintf(res, "0\n");
            fclose(res);
        }
#ifdef NDEBUG
        exit(ret ? 10 : 20);     // (faster than "return", which will invoke the destructor for 'Solver')
#endif
    }
}
<|endoftext|>


<commit_before>
#include <map>

#include "common_headers.h"

#include "debug.h"
#include "kernel.h"
#include "symbols.h"
#include "tagged_value.h"

namespace circa {

const int c_maxRuntimeSymbols = 2000;
struct RuntimeSymbol
{
    std::string name;
};

RuntimeSymbol g_runtimeSymbols[c_maxRuntimeSymbols];
int g_nextFreeSymbol = 0;
std::map<std::string,Symbol> g_stringToSymbol;

const char* symbol_get_text(Symbol symbol)
{
    // Runtime symbols
    if (symbol >= FirstRuntimeSymbol)
        return g_runtimeSymbols[symbol - FirstRuntimeSymbol].name.c_str();

    // Builtin symbols
    switch (symbol) {
        case EmptyName: return "";
        case InvalidSymbol: return "InvalidSymbol";
        case File: return "File";
        case Newline: return "Newline";
        case Out: return "Out";
        case Unknown: return "Unknown";
        case Repeat: return "Repeat";
        case Success: return "Success";
        case Failure: return "Failure";
        case FileNotFound: return "FileNotFound";
        case NotEnoughInputs: return "NotEnoughInputs";
        case TooManyInputs: return "TooManyInputs";
        case ExtraOutputNotFound: return "ExtraOutputNotFound";
        case PureCall: return "PureCall";
        case ControlFlowCall: return "ControlFlowCall";
        case Eager: return "Eager";
        case Range: return "Range";
        case Unevaluated: return "Unevaluated";
        case Lazy: return "Lazy";
    }

    internal_error("Unknown symbol in symbol_get_text");
    return "";
}

void symbol_get_text(Symbol symbol, String* string)
{
    set_string((TValue*) string, symbol_get_text(symbol));
}

Symbol as_symbol(TValue* tv)
{
    return tv->value_data.asint;
}

void symbol_value(Symbol name, TValue* tv)
{
    set_null(tv);
    tv->value_type = &SYMBOL_T;
    tv->value_data.asint = name;
}

void symbol_value(TValue* tv, Symbol name)
{
    symbol_value(name, tv);
}

void set_symbol(TValue* tv, Symbol val)
{
    set_null(tv);
    tv->value_type = &SYMBOL_T;
    tv->value_data.asint = val;
}

// Runtime symbols
Symbol string_to_symbol(const char* str)
{
    // Check if symbol is already registered
    std::map<std::string,Symbol>::const_iterator it;
    it = g_stringToSymbol.find(str);
    if (it != g_stringToSymbol.end())
        return it->second;

    Symbol index = g_nextFreeSymbol++;
    g_runtimeSymbols[index].name = str;
    Symbol symbol = index + FirstRuntimeSymbol;
    g_stringToSymbol[str] = symbol;
    return symbol;
}

} // namespace circa
<commit_msg>precalculate namespace fragments in symbols<commit_after>
#include <map>

#include "common_headers.h"

#include "debug.h"
#include "kernel.h"
#include "symbols.h"
#include "tagged_value.h"

namespace circa {

const int c_maxRuntimeSymbols = 2000;

struct RuntimeSymbol
{
    std::string str;
    Symbol namespaceParent;
};

RuntimeSymbol g_runtimeSymbols[c_maxRuntimeSymbols];
int g_nextFreeSymbol = 0;
std::map<std::string,Symbol> g_stringToSymbol;

const char* symbol_get_text(Symbol symbol)
{
    // Runtime symbols
    if (symbol >= FirstRuntimeSymbol)
        return g_runtimeSymbols[symbol - FirstRuntimeSymbol].str.c_str();

    // Builtin symbols
    switch (symbol) {
        case EmptyName: return "";
        case InvalidSymbol: return "InvalidSymbol";
        case File: return "File";
        case Newline: return "Newline";
        case Out: return "Out";
        case Unknown: return "Unknown";
        case Repeat: return "Repeat";
        case Success: return "Success";
        case Failure: return "Failure";
        case FileNotFound: return "FileNotFound";
        case NotEnoughInputs: return "NotEnoughInputs";
        case TooManyInputs: return "TooManyInputs";
        case ExtraOutputNotFound: return "ExtraOutputNotFound";
        case PureCall: return "PureCall";
        case ControlFlowCall: return "ControlFlowCall";
        case Eager: return "Eager";
        case Range: return "Range";
        case Unevaluated: return "Unevaluated";
        case Lazy: return "Lazy";
    }

    internal_error("Unknown symbol in symbol_get_text");
    return "";
}

void symbol_get_text(Symbol symbol, String* string)
{
    set_string((TValue*) string, symbol_get_text(symbol));
}

Symbol as_symbol(TValue* tv)
{
    return tv->value_data.asint;
}

void symbol_value(Symbol name, TValue* tv)
{
    set_null(tv);
    tv->value_type = &SYMBOL_T;
    tv->value_data.asint = name;
}

void symbol_value(TValue* tv, Symbol name)
{
    symbol_value(name, tv);
}

void set_symbol(TValue* tv, Symbol val)
{
    set_null(tv);
    tv->value_type = &SYMBOL_T;
    tv->value_data.asint = val;
}

// Runtime symbols
Symbol string_to_symbol(const char* str)
{
    // Check if symbol is already registered
    std::map<std::string,Symbol>::const_iterator it;
    it = g_stringToSymbol.find(str);
    if (it != g_stringToSymbol.end())
        return it->second;

    // Not yet registered; add it to the list.
    Symbol index = g_nextFreeSymbol++;
    g_runtimeSymbols[index].str = str;
    g_runtimeSymbols[index].namespaceParent = 0;
    Symbol symbol = index + FirstRuntimeSymbol;
    g_stringToSymbol[str] = symbol;

    // Search the string for a : symbol, from right to left. If found, the
    // left hand side will also become a symbol, and we'll update the
    // namespaceParent field.
    int len = strlen(str);
    for (int i=len - 1; i >= 0; i--) {
        if (str[i] == ':') {
            char* tempstr = strndup(str, i);
            g_runtimeSymbols[index].namespaceParent = string_to_symbol(tempstr);
            free(tempstr);
            break;
        }
    }

    return symbol;
}

} // namespace circa
<|endoftext|>