pax_global_header00006660000000000000000000000064152167714140014522gustar00rootroot0000000000000052 comment=4d8a9399575f6a8a89e3fa4c2591f21070e40250 math-comp-hierarchy-builder-4d8a939/000077500000000000000000000000001521677141400173565ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.gitattributes000066400000000000000000000000401521677141400222430ustar00rootroot00000000000000*.elpi linguist-language=prolog math-comp-hierarchy-builder-4d8a939/.github/000077500000000000000000000000001521677141400207165ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.github/workflows/000077500000000000000000000000001521677141400227535ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.github/workflows/main.yml000066400000000000000000000053331521677141400244260ustar00rootroot00000000000000# This is a basic workflow to help you get started with Actions name: docker CI # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: push: branches: [ master ] tags: [ "v*.*.*" ] pull_request: branches: [ master ] jobs: opam: runs-on: ubuntu-latest strategy: fail-fast: false matrix: coq_version: - '8.20' - '9.0' - '9.1' - '9.2' steps: - uses: actions/checkout@v2 - uses: coq-community/docker-coq-action@v1 with: opam_file: './rocq-hierarchy-builder.opam' coq_version: ${{ matrix.coq_version }} export: 'OPAMWITHTEST' # space-separated list of variables env: OPAMWITHTEST: 'true' release: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') needs: [opam] steps: - name: Checkout uses: actions/checkout@v3 - name: Inject slug/short variables uses: rlespinasse/github-slug-action@v4 - name: Create archive run: | VERSION="${GITHUB_REF_NAME_SLUG#v}" git archive -o hierarchy-builder-$VERSION.tar.gz --prefix=hierarchy-builder-$VERSION/ $GITHUB_SHA . - name: Release uses: softprops/action-gh-release@v1 with: files: hierarchy-builder-*.tar.gz fail_on_unmatched_files: true prerelease: true generate_release_notes: true name: Hierarchy Builder ${{ github.ref }} - name: Use OCaml 4.14.x uses: ocaml/setup-ocaml@v3 with: ocaml-compiler: 4.14.x opam-local-packages: | !coq-hierarchy-builder*.opam - name: Write PAT env: OPAM_PUBLISH_TOKEN: ${{ secrets.OPAM_PUBLISH_TOKEN }} run: | mkdir -p ~/.opam/plugins/opam-publish printf "$OPAM_PUBLISH_TOKEN" > ~/.opam/plugins/opam-publish/coqelpibot.token - name: Setup SSH uses: webfactory/ssh-agent@v0.8.0 with: ssh-private-key: ${{ secrets.BOT_SSH_KEY }} - name: Install opam-publish # 2.0.3 because more recent versions do not respect OPAMYES run: opam install -y -j 2 opam-publish=2.0.3 - name: Publish run: | eval $(opam env) git config --global user.name coqelpibot git config --global user.email coqelpibot@inria.fr OPAM_SUITE=released TAG=`git tag --sort=-v:refname|head -1` opam-publish --tag=$TAG --packages-directory=$OPAM_SUITE/packages --repo=coq/opam --no-browser -v ${TAG##v} https://github.com/math-comp/hierarchy-builder/releases/download/$TAG/hierarchy-builder-${TAG##v}.tar.gz math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.0.yml000066400000000000000000004005521521677141400270230ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - rocq-core - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.0\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.0" --argstr job "simple-io" name: Nix CI for bundle rocq-9.0 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.0.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.0.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.1.yml000066400000000000000000004005521521677141400270240ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - rocq-core - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.1\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.1" --argstr job "simple-io" name: Nix CI for bundle rocq-9.1 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.1.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.1.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-9.2.yml000066400000000000000000004026601521677141400270270ustar00rootroot00000000000000jobs: ExtLib: needs: - coq runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "QuickChick" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-bits" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coqeal" coquelicot: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coquelicot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"coquelicot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coquelicot" deriving: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-zify" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "rocq-core" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-9.2\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-9.2" --argstr job "simple-io" name: Nix CI for bundle rocq-9.2 on: pull_request: paths: - .github/workflows/nix-action-rocq-9.2.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-9.2.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.github/workflows/nix-action-rocq-master.yml000066400000000000000000004330141521677141400300070ustar00rootroot00000000000000jobs: ExtLib: needs: - coq - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (ExtLib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"ExtLib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" QuickChick: needs: - coq - mathcomp-boot - ExtLib - simple-io runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (QuickChick) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"QuickChick\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: simple-io' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "simple-io" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "QuickChick" bignums: needs: - rocq-core - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (bignums) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"bignums\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "bignums" coq: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" coq-bits: needs: - coq - mathcomp-algebra - mathcomp-algebra-tactics - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-bits) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq-bits\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra-tactics' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra-tactics" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-bits" coq-elpi: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coq-elpi) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coq-elpi\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" coqeal: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - bignums - multinomials - mathcomp-real-closed runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (coqeal) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"coqeal\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: bignums' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "bignums" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: multinomials' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "multinomials" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-real-closed' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-real-closed" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coqeal" deriving: needs: - coq - mathcomp-ssreflect - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (deriving) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"deriving\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "deriving" fourcolor: needs: - coq - mathcomp-boot - mathcomp-fingroup - mathcomp-algebra runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (fourcolor) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"fourcolor\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "fourcolor" hierarchy-builder: needs: - rocq-core - coq-elpi runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (hierarchy-builder) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"hierarchy-builder\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" mathcomp: needs: - rocq-core - mathcomp-character - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp" mathcomp-algebra: needs: - rocq-core - mathcomp-order - mathcomp-fingroup - hierarchy-builder - micromega-plugin runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-algebra\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" mathcomp-algebra-tactics: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - coq-elpi - mathcomp-zify runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-algebra-tactics) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-algebra-tactics\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq-elpi' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq-elpi" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-zify' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-zify" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra-tactics" mathcomp-analysis: needs: - coq - mathcomp-reals - mathcomp-field - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-analysis\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis" mathcomp-analysis-stdlib: needs: - coq - mathcomp-analysis - mathcomp-reals-stdlib - stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-analysis-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-analysis-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-analysis' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals-stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals-stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-analysis-stdlib" mathcomp-bigenough: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-bigenough) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-bigenough\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" mathcomp-boot: needs: - rocq-core - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-boot) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-boot\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" mathcomp-character: needs: - rocq-core - mathcomp-field - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-character) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-character\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" mathcomp-classical: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-finmap - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-classical) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-classical\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-classical" mathcomp-experimental-reals: needs: - coq - mathcomp-reals - mathcomp-bigenough - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-experimental-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-experimental-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-experimental-reals" mathcomp-field: needs: - rocq-core - mathcomp-solvable - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-field) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-field\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" mathcomp-fingroup: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-fingroup) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-fingroup\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" mathcomp-finmap: needs: - coq - mathcomp-boot runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-finmap) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-finmap\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" mathcomp-order: needs: - rocq-core - mathcomp-boot - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" mathcomp-real-closed: needs: - coq - mathcomp-ssreflect - mathcomp-algebra - mathcomp-field - mathcomp-fingroup - mathcomp-solvable - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-real-closed) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-real-closed\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-field' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-field" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-solvable' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-real-closed" mathcomp-reals: needs: - coq - mathcomp-classical - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-reals\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-classical' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-classical" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" mathcomp-reals-stdlib: needs: - coq - mathcomp-reals - stdlib - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-reals-stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-reals-stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"\ Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-reals' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-reals-stdlib" mathcomp-single: needs: - rocq-core - hierarchy-builder - micromega-plugin runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-single) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-single\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: micromega-plugin' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-single" mathcomp-solvable: needs: - rocq-core - mathcomp-algebra - hierarchy-builder runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-solvable) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-solvable\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: hierarchy-builder' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "hierarchy-builder" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-solvable" mathcomp-ssreflect: needs: - coq - mathcomp-boot - mathcomp-order runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-ssreflect) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-ssreflect\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-order' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-order" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" mathcomp-word: needs: - coq - mathcomp-algebra - mathcomp-ssreflect - mathcomp-fingroup - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-word) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-word\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-word" mathcomp-zify: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-fingroup - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (mathcomp-zify) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"mathcomp-zify\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-zify" micromega-plugin: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (micromega-plugin) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"micromega-plugin\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "micromega-plugin" multinomials: needs: - coq - mathcomp-boot - mathcomp-algebra - mathcomp-finmap - mathcomp-fingroup - mathcomp-bigenough runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (multinomials) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"multinomials\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-boot' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-boot" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-algebra' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-algebra" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-finmap' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-finmap" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-fingroup' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-fingroup" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-bigenough' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-bigenough" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "multinomials" odd-order: needs: - coq - mathcomp-character runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (odd-order) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"odd-order\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-character' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-character" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "odd-order" reglang: needs: - coq - mathcomp-ssreflect - stdlib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (reglang) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"reglang\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: mathcomp-ssreflect' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "mathcomp-ssreflect" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: stdlib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "reglang" rocq-core: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-core) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"rocq-core\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" rocq-elpi: needs: [] runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (rocq-elpi) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"rocq-elpi\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-elpi" simple-io: needs: - coq - ExtLib runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (simple-io) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"simple-io\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: coq' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "coq" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: ExtLib' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "ExtLib" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "simple-io" stdlib: needs: - rocq-core runs-on: ubuntu-latest steps: - name: Determine which commit to initially checkout run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"target_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n echo \"target_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.target_commit }} - name: Determine which commit to test run: "if [ ${{ github.event_name }} = \"push\" ]; then\n echo \"tested_commit=${{ github.sha }}\" >> $GITHUB_ENV\nelse\n merge_commit=$(git ls-remote ${{ github.event.repository.html_url }} refs/pull/${{ github.event.number }}/merge | cut -f1)\n mergeable=$(git merge --no-commit --no-ff ${{ github.event.pull_request.base.sha }} > /dev/null 2>&1; echo $?; git merge --abort > /dev/null 2>&1 || true)\n if [ -z \"$merge_commit\"\ \ -o \"x$mergeable\" != \"x0\" ]; then\n echo \"tested_commit=${{ github.event.pull_request.head.sha }}\" >> $GITHUB_ENV\n else\n echo \"tested_commit=$merge_commit\" >> $GITHUB_ENV\n\ \ fi\nfi\n" - name: Git checkout uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ env.tested_commit }} - name: Cachix install uses: cachix/install-nix-action@v31 with: nix_path: nixpkgs=channel:nixpkgs-unstable - name: Cachix setup math-comp uses: cachix/cachix-action@v16 with: authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} extraPullNames: coq, coq-community name: math-comp - id: stepGetDerivation name: Getting derivation for current job (stdlib) run: "NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link \\\n --argstr bundle \"rocq-master\" --argstr job \"stdlib\" \\\n --dry-run 2> err > out || (touch fail; true)\ncat out err\nif [ -e fail ]; then echo \"Error: getting derivation failed\"; exit 1; fi\n" - id: stepCheck name: Checking presence of CI target for current job run: "if $(cat out err | grep -q \"built:\") ; then\n echo \"CI target needs actual building\"\n if $(cat out err | grep -q \"derivations will be built:\"\ ) ; then\n echo \"waiting a bit for derivations that should be in cache\"\ \n sleep 30\n fi\nelse\n echo \"CI target already built\"\n echo \"\ status=fetched\" >> $GITHUB_OUTPUT\nfi\n" - if: steps.stepCheck.outputs.status != 'fetched' name: 'Building/fetching previous CI target: rocq-core' run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "rocq-core" - if: steps.stepCheck.outputs.status != 'fetched' name: Building/fetching current CI target run: NIXPKGS_ALLOW_UNFREE=1 nix-build --no-out-link --argstr bundle "rocq-master" --argstr job "stdlib" name: Nix CI for bundle rocq-master on: pull_request: paths: - .github/workflows/nix-action-rocq-master.yml pull_request_target: paths-ignore: - .github/workflows/nix-action-rocq-master.yml types: - opened - synchronize - reopened push: branches: - master math-comp-hierarchy-builder-4d8a939/.gitignore000066400000000000000000000010651521677141400213500ustar00rootroot00000000000000.*.aux *.a *.cma *.cmi *.cmo *.cmx *.cmxa *.cmxs *.glob *.ml.d *.ml4.d *.mli.d *.mllib.d *.mlpack.d *.native *.coq.d *.o *.v.d *.vio *.vos *.vok *.vo .coq-native/ .csdp.cache .lia.cache .nia.cache .nlia.cache .nra.cache csdp.cache lia.cache nia.cache nlia.cache nra.cache Makefile.coq Makefile.coq.conf .coqdeps.d Makefile.test-suite.coq Makefile.test-suite.coq.conf .coqdeps.test-suite *.v.hb *.v.hb.old coq.hb HB/common/log.compat.elpi _minted-* *.aux *.log *.out !*.v.out *.synctex.gz *.toc *.vrb *.fls *.nav *.bbl *.blg *.fdb_latexmk *.vtc *.dot config.stamp math-comp-hierarchy-builder-4d8a939/.nix/000077500000000000000000000000001521677141400202325ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/config.nix000066400000000000000000000052101521677141400222150ustar00rootroot00000000000000{ format = "1.0.0"; attribute = "hierarchy-builder"; default-bundle = "rocq-9.1"; bundles = let mcHBcommon = { mathcomp.override.version = "master"; }; coqMcHBcommon = { mathcomp.override.version = "master"; mathcomp.job = true; mathcomp-single.job = true; graph-theory.job = false; fourcolor.override.version = "master"; odd-order.override.version = "master"; mathcomp-finmap.override.version = "master"; mathcomp-classical.override.version = "master"; mathcomp-analysis.override.version = "master"; reglang.override.version = "master"; coq-bits.override.version = "master"; deriving.override.version = "master"; mathcomp-bigenough.override.version = "master"; multinomials.override.version = "master"; mathcomp-real-closed.override.version = "master"; coqeal.override.version = "master"; mathcomp-zify.override.version = "master"; mathcomp-algebra-tactics.override.version = "master"; mathcomp-word.override.version = "master"; coquelicot.override.version = "master"; ExtLib.override.version = "master"; simple-io.override.version = "master"; QuickChick.override.version = "master"; # jasmin.override.version = "main"; jasmin.job = false; # currently broken autosubst.job = false; ConCert.job = false; interval.job = false; }; in { "rocq-master" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "master"; stdlib.override.version = "master"; rocq-elpi.override.version = "master"; micromega-plugin.override.version = "master"; bignums.override.version = "master"; }; coqPackages = coqMcHBcommon // { coq.override.version = "master"; stdlib.override.version = "master"; coq-elpi.override.version = "master"; bignums.override.version = "master"; coquelicot.job = false; }; }; "rocq-9.2" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.2"; micromega-plugin.override.version = "master"; micromega-plugin.job = false; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.2"; }; }; "rocq-9.1" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.1"; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.1"; }; }; "rocq-9.0" = { rocqPackages = mcHBcommon // { rocq-core.override.version = "9.0"; }; coqPackages = coqMcHBcommon // { coq.override.version = "9.0"; }; }; }; cachix.coq = {}; cachix.coq-community = {}; cachix.math-comp.authToken = "CACHIX_AUTH_TOKEN"; } math-comp-hierarchy-builder-4d8a939/.nix/coq-nix-toolbox.nix000066400000000000000000000000531521677141400240120ustar00rootroot00000000000000"dd198b999f8526670a6f71a28bc1ea6ef7393cc5" math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/000077500000000000000000000000001521677141400226565ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/mathcomp-single/000077500000000000000000000000001521677141400257455ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.nix/coq-overlays/mathcomp-single/default.nix000066400000000000000000000000611521677141400301060ustar00rootroot00000000000000{ mathcomp }: mathcomp.override {single = true;} math-comp-hierarchy-builder-4d8a939/.vscode/000077500000000000000000000000001521677141400207175ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/.vscode/settings.json000066400000000000000000000074441521677141400234630ustar00rootroot00000000000000{ "spellright.language": [], "spellright.documentTypes": [ "markdown", "plaintext" ], "search.exclude": { ".*.aux": true, "*.a": true, "*.cma": true, "*.cmi": true, "*.cmo": true, "*.cmx": true, "*.cmxa": true, "*.cmxs": true, "*.glob": true, "*.ml.d": true, "*.ml4.d": true, "*.mli.d": true, "*.mllib.d": true, "*.mlpack.d": true, "*.native": true, "*.o": true, "*.v.d": true, "*.vio": true, "*.vo": true, ".coq-native/": true, ".csdp.cache": true, ".lia.cache": true, ".nia.cache": true, ".nlia.cache": true, ".nra.cache": true, "csdp.cache": true, "lia.cache": true, "nia.cache": true, "nlia.cache": true, "nra.cache": true, "Makefile.coq": true, "Makefile.coq.conf": true, ".coqdeps.d": true, "**/_minted-*": true, "**/*.aux": true, "**/*.log": true, // "**/*.out": true, // .v.out is used for expected test output "**/*.synctex.gz": true, "**/*.toc": true, "**/*.vrb": true, "**/*.fls": true, "**/*.nav": true, "**/*.bbl": true, "**/*.blg": true, "**/*.fdb_latexmk": true, "**/*.vtc": true }, "files.exclude": { ".*.aux": true, "*.a": true, "*.cma": true, "*.cmi": true, "*.cmo": true, "*.cmx": true, "*.cmxa": true, "*.cmxs": true, "*.glob": true, "*.ml.d": true, "*.ml4.d": true, "*.mli.d": true, "*.mllib.d": true, "*.mlpack.d": true, "*.native": true, "*.o": true, "*.v.d": true, "*.vio": true, "*.vo": true, ".coq-native/": true, ".csdp.cache": true, ".lia.cache": true, ".nia.cache": true, ".nlia.cache": true, ".nra.cache": true, "csdp.cache": true, "lia.cache": true, "nia.cache": true, "nlia.cache": true, "nra.cache": true, "Makefile.coq": true, "Makefile.coq.conf": true, ".coqdeps.d": true, "**/_minted-*": true, "**/*.aux": true, "**/*.log": true, // "**/*.out": true, // .v.out is used for expected test output "**/*.synctex.gz": true, "**/*.toc": true, "**/*.vrb": true, "**/*.fls": true, "**/*.nav": true, "**/*.bbl": true, "**/*.blg": true, "**/*.fdb_latexmk": true, "**/*.vtc": true, "**/.*.aux": true, "**/*.a": true, "**/*.cma": true, "**/*.cmi": true, "**/*.cmo": true, "**/*.cmx": true, "**/*.cmxa": true, "**/*.cmxs": true, "**/*.glob": true, "**/*.ml.d": true, "**/*.ml4.d": true, "**/*.mli.d": true, "**/*.mllib.d": true, "**/*.mlpack.d": true, "**/*.native": true, "**/*.coq.d": true, "**/*.o": true, "**/*.v.d": true, "**/*.vio": true, "**/*.vos": true, "**/*.vok": true, "**/*.vo": true, "**/.coq-native/": true, "**/.csdp.cache": true, "**/.lia.cache": true, "**/.nia.cache": true, "**/.nlia.cache": true, "**/.nra.cache": true, "**/csdp.cache": true, "**/lia.cache": true, "**/nia.cache": true, "**/nlia.cache": true, "**/nra.cache": true, "**/Makefile.coq": true, "**/Makefile.coq.conf": true, "**/.coqdeps.d": true, "**/Makefile.test-suite.coq": true, "**/Makefile.test-suite.coq.conf": true, "**/.coqdeps.test-suite": true, "**/*.dot": true } }math-comp-hierarchy-builder-4d8a939/AUTHORS.md000066400000000000000000000003251521677141400210250ustar00rootroot00000000000000Copyright (C) 2020 - Cyril Cohen (Inria) - Pierre Roux (Onera) - Kazuhiko Sakaguchi (University of Tsukuba) - Enrico Tassi (Inria) This software is released under the terms of the MIT license, see LICENSE file. math-comp-hierarchy-builder-4d8a939/Changelog.md000066400000000000000000000246501521677141400215760ustar00rootroot00000000000000# Changelog ## [1.10.3] - 2026-06-24 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - Rocq 9.2 with Rocq-Elpi 3.3.x - **Fix** Compilation on 9.2 ## [1.10.2] - 2026-01-28 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - **Fix** HB.howto - **Change** Blacklist internal HB constants - **Fix** Honour #[export] in HB.saturate ## [1.10.1] - 2025-09-08 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x - **Fix** HB.about ## [1.10.0] - 2025-07-21 Compatible with - Coq 8.20 with Coq-Elpi 3.0.x - Rocq 9.0 with Rocq-Elpi 3.0.x - Rocq 9.1 with Rocq-Elpi 3.0.x ## [1.9.1] - 2025-04-29 Drop compatibility with 8.18 and 8.19. Rename opma package to rocq-hierarchy-builder. ## [1.9.0] - 2025-04-15 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.4.x - Rocq 9.0 with Coq-Elpi 2.4.x Compile without coqc compatibility shim on Rocq 9.0 Compile without Stdlib on Rocq 9.0 ## [1.8.1] - 2025-01-25 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.4.x - Rocq 9.0 with Coq-Elpi 2.4.x ## [1.8.0] - 2024-12-14 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.2.x and 2.3.x ### General - **Bugfixes** several error messages have been fixed to display more faithful error messages. - **New warning** in case no instance is created. - **Bugfixes** the regression which forbad dependent functions to be instances has been fixed. ## [1.7.1] - 2024-12-06 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - Coq 8.20 with Coq-Elpi 2.2.x and 2.3.x ### General - **Speedup** `HB.instance` does not try to infer classes that inherit from a class that is known to have no instance (for the given type) - **Speedup** `toposort` on `gref` uses OCaml's maps and sets rather than lists ## [1.7.0] - 2024-01-10 Compatible with - Coq 8.18 with Coq-Elpi 2.0.0 - Coq 8.19 with Coq-Elpi 2.0.1 - **Removed** the `#[primitive_class]` attribute, making it the default. - **New** `HB.saturate` to saturate instances w.r.t. the current hierarchy - **Removed** the `#[infer]` attribute made obsolete by reverse coercions since Coq 8.16 ## [1.6.0] - 2023-09-20 Compatible with - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x - Coq 8.17 with Coq-Elpi 1.17.x and 1.18.x - Coq 8.18 with Coq-Elpi 1.19.x This version is required if Elpi is >= 1.17.0 ### General - **Speedup** speedup in coercion compression - **Speedup** accumulate clauses in batches (on Coq-Elpi >= 8.18.0) - **Change** remove generation of eta expanded instances (was unused) ## [1.5.0] - 2023-08-04 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x - Coq 8.17 with Coq-Elpi 1.17.x and 1.18.x - Coq 8.18 with Coq-Elpi 1.19.x This version is required if Elpi is >= 1.17.0 ### General - **Fix** spilling before predicate declaration - **Fix** unnecessary use of grafting slowing down compilation on MathComp 2.0 - **New** better "missing join" error message ## [1.4.0] - 2022-09-29 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x and 1.16.x ### General - **Fix** `HB.pack` works with structures about functions, and not just types. - **Fix** `HB.about` and `HB.graph` now display shortest names. - **New** Command `HB.howto` to find all possible ways to instanciate structures. - **New** Structures now support keys which type's head is a global reference. (Only keys corresponding to the coercion classes `Sortclass` and `Funclass` were accepted). ## [1.3.0] - 2022-07-27 Compatible with - Coq 8.15 with Coq-Elpi 1.14.x - Coq 8.16 with Coq-Elpi 1.15.x ### General - **Fix** Structures can be keyd on sorts (eg `Prop`) and products (eg `T -> U`) - **New** Mixin parameters can depend on structure instances inferred using previous mixins (see [this test](tests/interleave_context.v)) ## [1.2.1] - 2022-01-10 Compatible with - Coq 8.13 or 8.14 with Coq-Elpi 1.11.x - Coq 8.15 with Coq-Elpi 1.12.x ### General - **Fix** Do not unfold let-ins in instances (speedup) - **Fix** Test suite for Coq 8.15 ## [1.2.0] - 2021-09-24 Compatible with - Coq 8.13 or 8.14 with Coq-Elpi 1.11.x ### General - **Fix** Do not impose useless universe constraints on `option` and `prod` by using custom inductive types. - **New** Check for instances which break Forgetful Inheritance, attribute `#[non_forgetful_inheritance]` to disable the check. - **New** Factory instances are canonically (key `Factory.sort`) instances of all the structures they can fulfill. This can be used inside proofs to provide canonical instances on a type. E.g. `(factoryInstance : SomeStructure.sort _)` works if `factoryInstance` can be used to build `SomeStructure` - **New** `Strategy Opaque` for named mixins, improving conversion performance on generated terms - **New** Attributes `#[primitive]` and `#[primitive_class]` for `HB.structure/mixin/factory` to generate primitive records. - **New** Attribute `#[doc="text"]` supported by all commands and used by `HB.about` - **New** Attribute `#[hnf]` supported by `HB.instance` ### Commands - **New** `HB.locate` to find where an instance comes from - **New** `HB.about` to display HB specific info attached to a HB generated constant ### Tactics - **New** Tactic in term `HB.pack` and `HB.pack_for` taking a key `K` and a bunch of factories and building a structure instance on `K`. E.g. `pose K_fooType : Foo.type := HB.pack K f1 f2 ..` works if factories `f1 f2 ..` provide all mixins needed by structure `Foo`. ## [1.1.0] - 2021-03-30 Compatible with - Coq 8.11 with Coq-Elpi 1.6.2, - Coq 8.12 with Coq-Elpi 1.8.2, - Coq 8.13 with Coq-Elpi 1.9.5. ### General - **Experimental** support for structures with a function as the carrier, for e.g. hierarchies of morphisms. - **Fix** Type inference of parameters for HB commands improved, it can now rely on the right hand side of factories and mixins - **Fix** Removed a hack that included phantom fields in mixins and factories in order to prevent erasure from section discharge. - **Cosmetic** Changed naming convention for canonical instances e.g. `T_is_a_Ring` is now renamed to `T_Ring`. This name should still not be relied upon. - **Cleanup** The elpi code has been split into several files, one for each command and a folder for common code. - **Fix** Speedup `toposort` in elpi code. - **Doc** The file `structures.v` contains a detailed documentation of each command. ### Commands - **Deprecated** `HB.instance K F` in favor of `HB.instance Definition`. - **New** `HB.export` is like `Export` except that the module is stored in a database for later rexport. - **New** `HB.reexport` reexports all the modules that have been previously flagged by `HB.export`, as well as all the `HB.instance` that have been flagged by the attribute `#[export]`. - **New** `HB.check` is like `Check` but supports logging and can be disabled on a selection of Coq versions. - **New** `HB.graph` generates the graph of structures as a dot file. (One may use `tred file.dot | xdot -` to visualize the output). - **Extended** `HB.structure` to generate methods `.on` and `.copy` (see `structures.v` for their documentation). ### Attributes - **New** `#[export]` attribute can be given to `HB.instance` in order to have instances (re)declared by `HB.reexport`. - **New** `#[compress_coercions]` attribute (off by default) to shorten coercions paths in the synthesis of instances. When instanciating structures one by one, (e.g. T is declared as a Semiring, then as a Ring, then as a Field, etc) the coercions used to pile up, we now compress these chains of application. - **New** `#[log]` and `#[log(raw)]` to print Coq commands equivalent to what HB is doing. The raw print is the only one which is reparsable. - **New** `#[key="T"]` to flag paramter `T` as the key of the mixin/factory. The definition `indexed` used to serve this purpose is deprecated and will not do anything. - **New** `#[infer(P)]` can be used to tell `HB.structure` to set things up so that parameter `P` is automatically inferred. E.g. if `P : Ring.type` then `Structure.type` will take a `t : Type` and trigger a canonical inference. to infer the `t_is_a_Ring : Ring.type` associated to `t`. If `Structure` has a function carrier, one has to write `#[infer(P = "_ -> _")]`. - **New** `#[arg_sort]` for `HB.structure` generates an intermediate sort projection called `arg_sort` which is prioritary as a coercion and which unfolds to `sort`. It is meant to be the sort of arguments of operations (see `mathcomp/fingroup/fingroup.v` for more information). - **New** `#[local]` for `HB.instance` so that they do not survive sections. ### Tooling - **New** environment variable `COQ_ELPI_ATTRIBUTES="hb(log(raw))"` to have HB commands write patch files containing Coq commands equivalent to what HB did. These patch files have extension `.v.hb` and are named after the file they apply to. - **New** `coq.hb` command line utility to patch/reset files. - **New** The CI is now testing mathcomp and plan B (using nix). ## [1.0.0] - 2020-12-16 Requires Coq-Elpi 1.6 or 1.7 or 1.8 and Coq 8.11 or 8.12 or 8.13. - Use Coq's elaborator to typecheck factories and structures (coercions are now inserted properly) - New attribute `#[mathcomp]` for `HB.structure` to synthesize backward compatibility code for the Mathematical Components library. When the mixin contains a single axiom its name can be given as `#[mathcomp(axiom="eq_axiom")]`. - `HB.instance Definition name : factory T := term` works even if term is not a known builder. In this case the type (key) is read from the factory (the type of the definition). ## [0.10.0] - 2020-08-08 - HB now supports parameters (experimental). - Port to Coq-Elpi 1.5. - Better error message in case classes are not defined in the right order. - Structure operations are not reexported by substructures. - Spurious trivial `TYPE` structure removed from demo1. ## [0.9.1] - 2020-06-03 - `HB.instance` can be applied directly to a definition as in `HB.instance Definition foo := Bar.Build T ...` - Port to Coq-Elpi version 1.4 - Operations `op` from factory `f` are not bound to `f_op` anymore, they are now bound to `op` and potentially masked operations are accessible via `Super.op`. ## [0.9.0] - 2020-03-11 First public release for Coq 8.10 and 8.11. math-comp-hierarchy-builder-4d8a939/HB/000077500000000000000000000000001521677141400176475ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/HB/README.md000066400000000000000000000030001521677141400211170ustar00rootroot00000000000000## File structure - `HB/foo.elpi` implements the main entry point for `HB.foo` (or its variants) - `HB/common/foo.elpi` provides code used by more than one command - Each file `foo.elpi` should put its public API in the namespace `foo.` and its private code in `foo.private.`, if you need to access predicates in the private space then the API needs to be reworked (don't commit code accessing private stiff, even if Elpi won't prevent you from using it). ## Naming conventions - `under-foo.do! Arg [ Code ]` enriches the context with `foo`, the runs `std.do! [ Code ]` - `under-foo.then Arg F Out` enriches the context with `foo`, the runs `F Out`, as a consequence on can use the spilling expression `{under-foo.then Arg F}` - `foo_bar` projection from foo to its field bar - `foo->bar` conversion from type foo to type bar (it can be arbitrarily complex) - `get-foo` reads foo from the Coq world - `findall-foo` reads foo from `hb.db`, the output is sorted whenever it makes sense - `declare-foo` predicate adding to the Coq environment a `foo` - `postulate-foo` predicate assuming a `foo` (e.g. declaring a Coq section variable) - `TheType`, `TheClass`, `TheFoobar` the thing the current code is working on, eg the type of the structure begin defined - `FooAlias` see `phant-abbrev`, used to talk about the non canonical name of `Foo` - when foo is the constructor of a data type with type `A1 -> .. -> AN -> t` we define `mk-foo` as: `mk-foo A1 .. AN (foo A1 .. AN)` math-comp-hierarchy-builder-4d8a939/HB/about.elpi000066400000000000000000000352761521677141400216510ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace about { func main string ->. main S :- coq.locate-all S All, std.filter All (x\sigma gr a\ std.once (x = loc-gref gr ; x = loc-abbreviation a)) L, if (L = []) (coq.error "HB: unable to locate" S) true, std.forall L (about.main-located S). func main-located string, located ->. main-located S (loc-gref GR) :- class-def (class Class GR MLwP), !, private.main-structure S Class GR MLwP. main-located _ (loc-gref Class) :- class-def (class Class GR MLwP), !, gref->modname_short GR "." M, coq.gref->id GR St, S is M ^ "." ^ St, private.main-structure S Class GR MLwP. main-located S (loc-gref (indt I)) :- factory->constructor (indt I) _, !, private.main-factory S I. main-located S (loc-gref (const C)) :- factory->constructor (const C) _, !, private.main-factory-alias S C. main-located S (loc-gref (const C)) :- exported-op M _ C, !, private.main-operation S M C. main-located S (loc-gref GR) :- factory-alias->gref GR F ok, not (F = GR), !, main-located S (loc-gref F). main-located S (loc-abbreviation A) :- phant-abbrev GR PhB A, is-factory (indt F), factory->constructor (indt F) GR, !, private.main-factory->constructor S F PhB GR. main-located S (loc-abbreviation A) :- coq.notation.abbreviation-body A NArgs _, coq.notation.abbreviation A {coq.mk-n-holes NArgs} T, coq.safe-dest-app T (global GR) _, !, main-located S (loc-gref GR). main-located S (loc-gref GR) :- from Factory Mixin GR, !, private.main-builder S Factory Mixin. main-located S (loc-gref GR) :- std.filter {coq.CS.db-for _ (cs-gref GR)} (not1 unif-hint?) LV, coq.CS.db-for GR _ LP, std.filter {coq.coercion.db} (c\c = coercion GR _ _ _) LC, if (LV = [], LP = [], LC = []) (coq.error "HB: uninteresting constant" {coq.pp->string {private.pp-loc-of GR}}) true, if (not (LV = [])) (private.main-canonical-value S LV) true, if (not (LP = [])) (private.main-canonical-projection S GR LP) true, if (not (LC = [])) (private.main-coercion S LC) true. main-located S (loc-abbreviation _) :- coq.error "HB: unknown abbreviation" S. /* things also used in paths.elpi ------------------------------------------ */ shorten coq.pp.{ v , h, hv, hov , spc , str , box , glue , brk , empty }. func bulletize1 (func A -> coq.pp), A -> coq.pp. bulletize1 F X (glue [str "- ", M]) :- F X M. % @gares func bulletize list A, (func A -> coq.pp) -> coq.pp. bulletize [] _ empty :- !. bulletize L F (glue [brk 0 0 | PLB]) :- std.map L (bulletize1 F) PL, std.intersperse (brk 0 0) PL PLB. % Print shortest qualified identifier of the module containing a gref func pp-module gref -> coq.pp. pp-module GR (str ID) :- gref->modname_short GR "." ID. func unif-hint? cs-instance -> . unif-hint? (cs-instance _ (cs-gref GR) _) :- coq.CS.db-for GR _ [_|_]. func not1 (pred i:A), A. not1 P X :- not (P X). /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.pp.{ v , h, hv, hov , spc , str , box , glue , brk , empty }. func docstring-for-file string -> prop. docstring-for-file Rex (docstring Loc Doc) :- docstring Loc Doc, loc.fields Loc File _ _ _ _, rex.match {calc(".*" ^ Rex)} File, !. func main-canonical-value string, list cs-instance ->. main-canonical-value S CanonicalValues :- group-by-loc CanonicalValues CanonicalValuesL, %format PpCanonicalValues = box (v 4) [ str "HB: ", str S, str " is canonically equipped with structures:", {bulletize CanonicalValuesL pp-canonical-solution-list}], % print coq.say {coq.pp->string PpCanonicalValues}, coq.say. func group-by-loc list cs-instance -> list (pair (option loc) (list cs-instance)). group-by-loc [] []. group-by-loc [cs-instance P V GR|L] [pr (some Loc) [cs-instance P V GR|SameLoc]|Rest1] :- decl-location GR Loc, !, std.partition L (x\ sigma GR1\ x = cs-instance _ _ GR1, decl-location GR1 Loc) SameLoc Rest, group-by-loc Rest Rest1. group-by-loc [I|Rest] [pr none [I]|Rest1] :- group-by-loc Rest Rest1. func pp-canonical-solution-list pair (option loc) (list cs-instance) -> coq.pp. pp-canonical-solution-list (pr none [CS]) Pp :- pp-canonical-solution CS Pp. pp-canonical-solution-list (pr (some Loc) L) Pp :- Pp = box (v 0) { std.append {std.intersperse spc {std.map L pp-canonical-solution}} [ spc, {pp-loc Loc} ] }. func pp-canonical-solution cs-instance -> coq.pp. pp-canonical-solution (cs-instance _Proj _Pat GR) Pp :- coq.env.typeof GR T, coq.prod-tgt->gref T F, if (class-def (class _ F _)) (gref->modname_short F "." ID) (coq.gref->string F ID), Pp = box (hov 0) [ str ID ]. func main-canonical-projection string, gref, list cs-instance. main-canonical-projection S Proj CanonicalProjectionValues :- %format PpCanonicalProjectionOrigin = box (hov 4) [ str "HB:", spc, str S, spc, str "is a canonical projection", spc, {pp-loc-of Proj}], PpCanonicalProjectionValues = box (v 4) [ str "HB: ", str S, str " has the following canonical values:", {bulletize CanonicalProjectionValues pp-canonical-value}], % print coq.say {coq.pp->string PpCanonicalProjectionOrigin}, coq.say {coq.pp->string PpCanonicalProjectionValues}, coq.say. func pp-canonical-value cs-instance -> coq.pp. pp-canonical-value (cs-instance _Proj (cs-gref GR) _Sol) Pp :- coq.term->pp (global GR) V, Pp = box (hov 2) [ V , spc, {pp-loc-of GR} ]. func main-coercion string, list coercion. main-coercion S [coercion GR _ Src Tgt|_] :- % format if (class-def (class _ Src _) ; class-def (class Src _ _)) (Source = str {gref->modname_short Src "."}) (coq.term->pp (global Src) Source), if2 (Tgt = grefclass TGR) (if (class-def (class _ TGR _) ; class-def (class TGR _ _)) (Target = str {gref->modname_short TGR "."}) (coq.term->pp (global TGR) Target)) (Tgt = sortclass) (Target = str "Sortclass") (Target = str "Funclass"), PpCoercionOrigin = box (hov 4) [ str "HB:", spc, str S, spc, str "is a coercion from", spc, Source, str" to ", Target, spc, {pp-loc-of GR}], % print coq.say {coq.pp->string PpCoercionOrigin}, coq.say. func main-operation string, mixinname, constant -> . main-operation S MixinSource _ :- % fetch mixin->first-class MixinSource Class, class-def (class Class Structure _), !, % format PpOriginStructure = box (hov 4) [ str "HB:", spc, str S, spc, str "is an operation of structure", spc, {pp-module Structure}, spc, {pp-loc-of Structure}], PpOriginMixin = box (hov 4) [ str "HB:", spc, str S, spc, str "comes from mixin", spc, {pp-module MixinSource}, spc, {pp-loc-of MixinSource}], % print coq.say {coq.pp->string PpOriginStructure}, coq.say {coq.pp->string PpOriginMixin}, coq.say. func main-structure string, classname, structure, mixins. main-structure S Class Structure MLwP :- % fetch list-w-params_list MLwP ML, std.map-filter ML (m\r\ sigma P O OPS\ mixin->first-class m Class, std.findall (exported-op m P O) OPS, std.map OPS (c\out\ sigma p\ c = exported-op m p out) r) OPLL, std.flatten OPLL Operations, std.map {std.findall (sub-class Class CS_ CoeS_ NS_)} (x\r\ x = sub-class Class r _ _) SubClasses, std.map {std.findall (sub-class Cs_ Class Coes_ Ns_)} (x\r\ x = sub-class r Class _ _) SuperClasses, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a structure", spc, {pp-loc-of Structure} ], PpOperations = box (v 4) [ str "HB: ", str S, str " characterizing operations and axioms are:", {bulletize Operations pp-const}], PpClass = box (v 4) [ str "HB: ", {pp-module Class}, str " is a factory for the following mixins:", {bulletize ML (m\r\ sigma tmp\ if (mixin->first-class m Class) (pp-module m tmp, r = glue [tmp, str " (* new, not from inheritance *)"]) (pp-module m r))}], PpSubClasses = box (v 4) [ str "HB: ", {pp-module Class}, str " inherits from:", {bulletize SubClasses pp-module}], PpSuperClasses = box (v 4) [ str "HB: ", {pp-module Class}, str " is inherited by:", {bulletize SuperClasses pp-module}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpOperations}, coq.say {coq.pp->string PpClass}, coq.say {coq.pp->string PpSubClasses}, coq.say {coq.pp->string PpSuperClasses}, print-docstring Structure, coq.say. func main-factory->constructor string, inductive, gref, gref. main-factory->constructor S F PhBuild Build :- % fetch gref->deps Build DMLwP, list-w-params_list DMLwP DML, factory-provides (indt F) PMLwP, list-w-params_list PMLwP PML, coq.env.projections F FieldsOpts, std.map-filter FieldsOpts (x\r\ x = some r) Fields, coq.arguments.implicit PhBuild [Implicits], compute-arg-type DMLwP Fields [] ParamsNames TName FieldsNames ArgsTypes, compute-field-info FieldsNames Implicits FieldsNamesInfo, std.map ParamsNames (n\r\r = str n) ParamsPp, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a factory constructor", spc, {pp-loc-of Build} ], PpRequires = box (v 4) [ str "HB: ", str S, str " requires its subject to be already equipped with:", {bulletize DML pp-module}], PpProvides = box (v 4) [ str "HB: ", str S, str " provides the following mixins:", {bulletize PML pp-module}], PpUsage = box (v 4) [box h {std.intersperse spc [ str "HB: arguments:", glue {std.intersperse spc [str S | ParamsPp]}, str TName, glue FieldsNamesInfo]}, {bulletize ArgsTypes pp-arg-type}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpRequires}, coq.say {coq.pp->string PpProvides}, coq.say {coq.pp->string PpUsage}, print-docstring Build, coq.say. func compute-arg-type list-w-params mixinname, list constant, list term -> list id, id, list id, list (pair id coq.pp). compute-arg-type (w-params.cons ID Ty Rest) F Acc [ID|PN] TN FN [pr ID PPTy |Xs] :- coq.term->pp Ty PPTy, @pi-parameter ID Ty x\ compute-arg-type (Rest x) F [x|Acc] PN TN FN Xs. compute-arg-type (w-params.nil ID Ty Rest) F Acc [] ID FN [pr ID PPTy|Xs] :- coq.term->pp Ty PPTy, @pi-parameter ID Ty x\ compute-arg-type.fields F {std.length (Rest x)} {std.rev [x|Acc]} Xs FN. :index(1) func compute-arg-type.fields list constant, int, list term -> list (pair id coq.pp), list id. compute-arg-type.fields [] _ _ [] []. compute-arg-type.fields [C|Cs] NDeps Args [pr ID PPTy|Xs] [ID|FN] :- exported-op _ C OP, !, coq.env.typeof (const OP) Ty, coq.gref->id (const OP) ID, coq.subst-prod Args Ty TyArgs, (@pplevel! 200 => coq.term->pp TyArgs PPTy), compute-arg-type.fields Cs NDeps Args Xs FN. compute-arg-type.fields [OP|Cs] NDeps Args [pr ID PPTy|Xs] [ID|FN] :- % factories don't get exported ops, so we hack their types :-/ coq.env.typeof (const OP) OrigTy, copy OrigTy Ty, coq.gref->id (const OP) ID, coq.subst-prod Args Ty TyArgs, coq.mk-n-holes NDeps Deps, coq.subst-prod Deps TyArgs TyArgsDeps, coq.subst-prod [_] TyArgsDeps TyArgsDepsRecord, ToDrop is NDeps + 2, (@pplevel! 200 => coq.term->pp TyArgsDepsRecord PPTy), @pi-parameter ID TyArgsDepsRecord op\ (pi L L1 X\ copy (app[global(const OP)|L]) X :- std.drop ToDrop L L1, coq.mk-app op L1 X, !) => compute-arg-type.fields Cs NDeps Args Xs FN. func main-factory string, inductive. main-factory S Factory :- % fetch coq.env.projections Factory Ps, std.map-filter Ps (x\r\ x = some r) Fields, gref->deps (indt Factory) DMLwP, list-w-params_list DMLwP DML, factory-provides (indt Factory) PMLwP, list-w-params_list PMLwP PML, % format PpOrigin = box (hov 4) [ str "HB: ", str S, str " is a factory", spc, {pp-loc-of (indt Factory)} ], PpOperations = box (v 4) [ str "HB: ", str S, str " operations and axioms are:", {bulletize Fields pp-const}], PpRequires = box (v 4) [ str "HB: ", str S, str " requires the following mixins:", {bulletize DML pp-module}], PpProvides = box (v 4) [ str "HB: ", str S, str " provides the following mixins:", {bulletize PML pp-module}], % print coq.say {coq.pp->string PpOrigin}, coq.say {coq.pp->string PpOperations}, coq.say {coq.pp->string PpRequires}, coq.say {coq.pp->string PpProvides}, print-docstring (indt Factory), coq.say. func main-factory-alias string, constant. main-factory-alias S _Const :- coq.say "HB: todo HB.about for factory alias" S. func main-builder string, factoryname, mixinname. main-builder _S From To :- coq.say "HB: todo HB.about for builder from" {gref->modname_short From "."} "to" {gref->modname_short To "."}. func compute-field-info.aux list id, list implicit_kind -> list coq.pp. compute-field-info.aux [] _ []. compute-field-info.aux [Name|NS] [explicit|IS] [str Name|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [implicit|IS] [glue[str"[",str Name,str"]"]|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [maximal|IS] [glue[str"{",str Name,str"}"]|PS] :- compute-field-info.aux NS IS PS. compute-field-info.aux [Name|NS] [] [str Name|PS] :- compute-field-info.aux NS [] PS. func compute-field-info list id, list implicit_kind -> list coq.pp. compute-field-info Names Impls O :- compute-field-info.aux {std.rev Names} {std.rev Impls} Pp, std.intersperse spc {std.rev Pp} O. func pp-const constant -> coq.pp. pp-const F (str ID) :- coq.gref->id (const F) ID. func pp-arg-type pair id coq.pp -> coq.pp. pp-arg-type (pr ID PPTy) (box (hov 2) [str ID, str" :", spc, PPTy]). :functional pred pp-if-verbose o:coq.pp, i:(func -> coq.pp). pp-if-verbose V P :- get-option "verbose" tt, !, P V. pp-if-verbose empty _. func pp-loc-of gref -> coq.pp. pp-loc-of GR PP :- decl-location GR Loc, !, pp-loc Loc PP. pp-loc-of _ coq.pp.empty. func pp-loc loc -> coq.pp. pp-loc Loc (coq.pp.glue PP) :- loc.fields Loc File _ _ Line _, QFile is "\"" ^ File ^ "\", line " ^ {std.any->string Line}, PP = [str "(from ", str QFile, str")"]. func docstring->pp string -> coq.pp. docstring->pp Txt (glue Doc) :- rex.replace "\n" " " Txt PlainTxt, rex.split " " PlainTxt Words, std.filter Words (w\not (w = "")) NEWords, std.map NEWords (w\r\ r = str w) PpWords, std.intersperse spc PpWords Doc. func docstring-of gref -> option coq.pp. docstring-of GR (some Doc) :- decl-location GR Loc, docstring Loc Txt, !, docstring->pp Txt Doc. docstring-of _ none. func pp-docstring-of gref -> coq.pp. pp-docstring-of GR D :- docstring-of GR (some D), !. pp-docstring-of _ coq.pp.empty. func print-docstring gref ->. print-docstring GR :- if (docstring-of GR (some Doc)) (coq.say {coq.pp->string (box (hov 5) [str"Doc: ",Doc])}) true. }} math-comp-hierarchy-builder-4d8a939/HB/builders.elpi000066400000000000000000000137371521677141400223460ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace builders { func begin context-decl ->. begin CtxSkel :- std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module", if-verbose (coq.say {header} "begin module for builders"), log.coq.env.begin-module Name none, builders.private.factory CtxSkel IDF GRF, % the Super module to access operations/axioms shadowed by the ones in the factory if-verbose (coq.say {header} "begin module Super"), log.coq.env.begin-module "Super" none, if (GRF = indt FRecord) (std.do! [ std.forall {coq.env.projections FRecord} builders.private.declare-shadowed-constant, ]) true, if-verbose (coq.say {header} "ended module Super"), log.coq.env.end-module-name "Super" _, log.coq.env.begin-section Name, if-verbose (coq.say {header} "postulating factories"), builders.private.postulate-factories Name IDF CtxSkel . } % "end" is a keyword, be put it in the namespace by hand func builders.end. builders.end :- std.do! [ current-mode (builder-from _ _ _ ModName), log.coq.env.end-section-name ModName, findall-builders LFIL, std.fold LFIL [] builders.private.declare-1-builder Clauses, if (Clauses = []) (coq.error "No builders to declare, did you forget HB.instance?") true, std.findall (abbrev-to-export F_ N_ A_) ExportClauses, coq.env.current-path CurModPath, std.filter ExportClauses (export.private.abbrev-in-module CurModPath) ExportClausesFiltered, % TODO: Do we need this module? std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module", log.coq.env.begin-module Name none, acc-clauses current Clauses, acc-clauses current ExportClausesFiltered, log.coq.env.end-module-name Name Exports, log.coq.env.end-module-name ModName _, export.module {calc (ModName ^ "." ^ Name)} Exports, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ func factory.cdecl->w-mixins context-decl -> w-mixins context-decl. namespace builders.private { % [declare-1-builder (builder _ F M B) From MoreFrom] Given B of type FB, it % declares all the new builders F to M via B. % From holds the (from F Mi Bi) new clauses during folding. :index (1) func declare-1-builder builder, list prop -> list prop. declare-1-builder (builder _ SrcFactory TgtMixin _) FromClauses FromClauses :- (FromClauses => from SrcFactory TgtMixin _), !, if-verbose (coq.say {header} "skipping duplicate builder from" {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}). declare-1-builder (builder _ SrcFactory TgtMixin B) FromClauses [from SrcFactory TgtMixin B|FromClauses] :- if-verbose (coq.say {header} "declare builder from" {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}). % We add breviations for all constants what will be shadowed by projections % if the factory. :index (1) func declare-shadowed-constant option constant ->. declare-shadowed-constant none. declare-shadowed-constant (some C) :- coq.gref->id (const C) Id, std.forall {coq.locate-all Id} (declare-shadowed-located Id). :index (_ 1) func declare-shadowed-located string, located. declare-shadowed-located Id (loc-gref GR) :- @global! => log.coq.notation.add-abbreviation Id 0 (global GR) ff _. declare-shadowed-located Id (loc-abbreviation Abbrev) :- coq.notation.abbreviation-body Abbrev NArgs T, @global! => log.coq.notation.add-abbreviation Id NArgs T ff _. func postulate-factory-abbrev term, list term, id, factoryname -> term. postulate-factory-abbrev TheType Params Name Falias TheFactory :- std.do! [ std.assert-ok! (factory-alias->gref Falias F) "HB", phant-abbrev F _ Fabv, coq.notation.abbreviation Fabv {std.append Params [TheType]} Package, Msg is "Unable to declare factory " ^ Name, std.assert-ok! (coq.typecheck-ty Package _) Msg, log.coq.env.add-section-variable-noimplicits Name Package C, TheFactory = global (const C), ]. % Only record fields can be exported as operations. :index (1) func define-factory-operations term, list term, term, gref. define-factory-operations TheType Params TheFactory (indt I) :- !, coq.env.indt I _ NIParams _ _ _ _, NHoles is NIParams - 1 - {std.length Params}, coq.env.projections I PL, std.forall PL (define-factory-operation TheType Params TheFactory NHoles). define-factory-operations _ _ _ _. :index (_ _ _ _ 1) func define-factory-operation term, list term, term, int, option constant. define-factory-operation _ _ _ _ none. define-factory-operation TheType Params TheFactory NHoles (some P) :- coq.mk-n-holes NHoles Holes, std.append Holes [TheFactory] Holes_Factory, std.append Params [TheType|Holes_Factory] Args, T = app[global (const P)|Args], std.assert-ok! (coq.typecheck T _) "Illtyped applied factory operation", coq.gref->id (const P) Name, @local! => log.coq.notation.add-abbreviation Name 0 T ff _. func factory context-decl -> string, gref. factory (context-item IDF _ T _ _\ context-end) IDF GR :- !, coq.safe-dest-app T (global GR) _. factory (context-item _ _ _ _ R) IDF GR :- !, pi x\ factory (R x) IDF GR. factory _ _ _ :- !, coq.error "the last context item is not a factory". func postulate-factories id, string, context-decl. postulate-factories ModName IDF CDecl :- factory.cdecl->w-mixins CDecl (pr FLwP _), context.declare.params-key FLwP ParamsSection FKey FLwA, std.assert! (FLwA = [triple GRF _ _]) "HB: cannot declare builders for more than one factory at a time", gref->deps GRF DepswPRaw, context.declare.mixins FKey ParamsSection DepswPRaw _ _ _, std.map ParamsSection triple_2 FParams, postulate-factory-abbrev FKey FParams IDF GRF TheFactory, define-factory-operations FKey FParams TheFactory GRF, acc-clause current (current-mode (builder-from FKey TheFactory GRF ModName)). }math-comp-hierarchy-builder-4d8a939/HB/common/000077500000000000000000000000001521677141400211375ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/HB/common/compat_acc_clauses_all.elpi000066400000000000000000000002261521677141400264520ustar00rootroot00000000000000:index (1) func acc-clauses scope, list prop. acc-clauses Scope CL :- coq.elpi.accumulate-clauses Scope "hb.db" {std.map CL (c\r\ r = clause _ _ c)}. math-comp-hierarchy-builder-4d8a939/HB/common/compat_add_secvar_all.elpi000066400000000000000000000010351521677141400262770ustar00rootroot00000000000000func log.coq.env.add-section-variable-noimplicits id, term -> constant. log.coq.env.add-section-variable-noimplicits Name Ty C :- if (Name = "_") (ID is "fresh_name_" ^ {std.any->string {new_int}}) (ID = Name), % elpi:if version coq-elpi < 2.4.0 @local! => coq.env.add-section-variable ID Ty C, % elpi:endif % elpi:if version coq-elpi >= 2.4.0 @local! => coq.env.add-section-variable ID _ Ty C, % elpi:endif log.private.log-vernac (log.private.coq.vernac.variable ID Ty), @local! => log.coq.arguments.set-implicit (const C) [[]]. math-comp-hierarchy-builder-4d8a939/HB/common/database.elpi000066400000000000000000000414331521677141400235630ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. %%%%%%%%% HB database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func from_factory prop -> factoryname. from_factory (from X _ _) X. func from_mixin prop -> mixinname. from_mixin (from _ X _) X. func from_builder prop -> term. from_builder (from _ _ X) (global X). func mixin-src_mixin prop -> mixinname. mixin-src_mixin (mixin-src _ M _) M. func mixin-src_src prop -> term. mixin-src_src (mixin-src _ _ S) S. func local-canonical-gref prop -> constant. local-canonical-gref (local-canonical C) C. func class_name hbclass -> classname. class_name (class N _ _) N. func class_structure hbclass -> structure. class_structure (class _ S _) S. func class-def_name prop -> classname. class-def_name (class-def (class N _ _)) N. func mixin-class_class prop -> classname. mixin-class_class (mixin-class _ C) C. func mixin-class_mixin prop -> mixinname. mixin-class_mixin (mixin-class M _) M. func classname->def classname -> hbclass. classname->def CN (class CN S ML) :- class-def (class CN S ML), !. func classname->mixins classname -> mixins. classname->mixins CN MLwP :- class-def (class CN _ MLwP), !. func module-to-export_module prop -> modpath. module-to-export_module (module-to-export _ _ M) M. func module-to-export_module-nice prop -> id. module-to-export_module-nice (module-to-export _ M _) M. func instance-to-export_instance prop -> constant. instance-to-export_instance (instance-to-export _ _ M) M. func instance-to-export_instance-nice prop -> id. instance-to-export_instance-nice (instance-to-export _ M _) M. func abbrev-to-export_name prop -> id. abbrev-to-export_name (abbrev-to-export _ N _) N. func abbrev-to-export_body prop -> term. abbrev-to-export_body (abbrev-to-export _ _ B) (global B). func clause-to-export_clause prop -> prop. clause-to-export_clause (clause-to-export _ C) C. func extract-builder prop -> builder. extract-builder (builder-decl B) B. func leq-builder builder, builder ->. leq-builder (builder N _ _ _) (builder M _ _ _) :- N =< M. func sub-class? hbclass, hbclass ->. sub-class? (class C1 _ ML1P) (class C2 _ ML2P) :- not (C1 = C2), list-w-params_list ML1P ML1, list-w-params_list ML2P ML2, std.forall ML2 (m2\ std.exists! ML1 (m1\ m1 = m2)). % [factory-provides F MLwP] computes the mixins MLwP generated by F func factory-provides factoryname -> mixins. factory-provides FactoryAlias MLwP :- std.do! [ std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB", gref->deps Factory RMLwP, w-params.map RMLwP (factory-provides.base Factory) MLwP ]. func mixin->factories mixinname -> list factoryname. mixin->factories M FL :- std.do! [ std.findall (from F_ M B_) AllF, std.map AllF from_factory FL ]. :index(1) func factory-provides.base factoryname, list term, term, list (w-args mixinname) -> list (w-args mixinname). factory-provides.base Factory Params T _RMLwP MLwP :- std.do! [ std.findall (from Factory T_ F_) All, std.map All from_mixin ML, std.map All from_builder BL, std.map2 BL ML (factory-provides.one Params T) MLwP, ]. func factory-provides.one list term, term, term, mixinname -> w-args mixinname. factory-provides.one Params T B M (triple M PL T) :- std.do! [ std.assert-ok! (coq.typecheck B Ty) "Builder illtyped", subst-prod [T] {subst-prod Params Ty} TyParams, std.assert! (extract-conclusion-params T TyParams PL) "The conclusion of a builder is a mixin whose parameters depend on other mixins", ]. func extract-conclusion-params term, term -> list term. extract-conclusion-params TheType (prod _ S T) R :- !, @pi-decl _ S x\ extract-conclusion-params TheType (T x) R. extract-conclusion-params TheType (app [global GR|Args]) R :- !, std.do! [ std.assert-ok! (factory-alias->gref GR Factory) "HB", factory->nparams Factory NP, std.map Args (copy-pack-holes TheType TheType) NewArgs, std.take NP NewArgs R]. extract-conclusion-params TheType T R :- whd1 T T1, !, extract-conclusion-params TheType T1 R. % [factories-provide FL ML] computes the mixins ML generated by all F in FL % % cons tp p\ nil t\ [pr f1 [p,t]] % f1 p t = m1 t, m2 p t % cons tp p\ nil t\ [pr m1 [t], pr m2 [p,t]] func factories-provide list-w-params factoryname -> mixins. factories-provide FLwP MLwP :- list-w-params.flatten-map FLwP factory-provides UnsortedMLwP, w-params.map UnsortedMLwP (p\t\ toposort-mixins) MLwP. func undup-grefs list gref -> list gref. undup-grefs L UL :- coq.gref.list->set L S, coq.gref.set.elements S UL. func undup-sorts list sort -> list sort. undup-sorts L R :- if (std.mem L prop) (R1 = [prop]) (R1 = []), if (std.mem L sprop) (R2 = [sprop]) (R2 = []), if (std.mem L (typ _)) (R3 = [typ _]) (R3 = []), std.flatten [R1, R2, R3] R. % also prunes cs-default func undup-cs-patterns list cs-pattern -> list cs-pattern. undup-cs-patterns L R :- std.map-filter L (x\r\ x = cs-gref r) LGR, undup-grefs LGR ULGR, std.map ULGR (x\r\ r = cs-gref x) R1, std.map-filter L (x\r\ x = cs-sort r) LS, undup-sorts LS ULS, std.map ULS (x\r\ r = cs-sort x) R2, if (std.mem L cs-prod) (R3 = [cs-prod]) (R3 = []), std.flatten [R1, R2, R3] R. % Mixins can be topologically sorted according to their dependencies func toposort-mixins list (w-args mixinname) -> list (w-args mixinname). toposort-mixins In Out :- std.map In triple_1 ML, std.map ML (m\r\sigma D D1\ gref->deps m D1, list-w-params_list D1 D, std.map D (d\r\r = pr d m) r) ES2, std.flatten ES2 ES, toposort-proj triple_1 ES In Out. func toposort-proj (func A -> gref), list (pair gref gref), list A -> list A. toposort-proj Proj ES In Out :- !, toposort-proj.acc Proj ES [] In Out. func topo-find B -> A. func toposort-proj.acc (pred i:A, o:gref), list (pair gref gref), list gref, list A -> list A. toposort-proj.acc _ ES Acc [] Out :- !, std.map {std.gref.toposort ES Acc} topo-find Out, !. toposort-proj.acc Proj ES Acc [A|In] Out :- std.do![ Proj A B, topo-find B A => toposort-proj.acc Proj ES [B|Acc] In Out ]. % Classes can be topologically sorted according to the subclass relation func toposort-classes.mk-class-edge prop -> pair classname classname. toposort-classes.mk-class-edge (sub-class C1 C2 _ _) (pr C2 C1). func toposort-classes list classname -> list classname. toposort-classes In Out :- std.do! [ std.findall (sub-class C1_ C2_ _ _) SubClasses, std.map SubClasses toposort-classes.mk-class-edge ES, std.gref.toposort ES In Out, ]. func findall-classes -> list hbclass. findall-classes CLSortedDef :- std.do! [ std.findall (class-def C_) All, std.map All class-def_name CL, toposort-classes CL CLSorted, std.map CLSorted classname->def CLSortedDef, ]. func findall-classes-for.unsorted list mixinname, list classname -> list classname. findall-classes-for.unsorted [] CL CL :- !. findall-classes-for.unsorted [M|ML] CLAcc Out :- std.do! [ std.findall (mixin-class M C_) All, std.map All mixin-class_class CL, findall-classes-for.unsorted ML {std.append CL CLAcc} Out ]. func findall-classes-for list mixinname -> list hbclass. findall-classes-for ML CLSortedDef :- std.do! [ findall-classes-for.unsorted ML [] CL, toposort-classes CL CLSorted, std.map CLSorted classname->def CLSortedDef, ]. func findall-builders -> list builder. findall-builders LFIL :- std.map {std.findall (builder-decl B_)} extract-builder LFILunsorted, std.bubblesort LFILunsorted leq-builder LFIL. func findall-has-mixin-instance cs-pattern -> list prop. findall-has-mixin-instance P CL :- std.findall (has-mixin-instance P _ _) CL. func has-mixin-instance_key prop -> cs-pattern. has-mixin-instance_key (has-mixin-instance P _ _) P. func findall-mixin-src term -> list mixinname. findall-mixin-src T ML :- std.map {std.findall (mixin-src T M_ V_)} mixin-src_mixin ML. func findall-factory->constructor -> list prop. findall-factory->constructor L :- std.map {std.findall (findall-factory->constructor.aux _)} findall-factory->constructor.make L. pred findall-factory->constructor.aux o:prop. findall-factory->constructor.aux (factory->constructor F C) :- is-factory F, factory->constructor F C. func findall-factory->constructor.make prop -> prop. findall-factory->constructor.make (findall-factory->constructor.aux P) P. func findall-local-canonical -> list constant. findall-local-canonical CL :- std.map {std.findall (local-canonical C_)} local-canonical-gref CL. % [distinct-pairs-below C AllSuper C1 C2] finds C1 and C2 in % AllSuper (all super classes of C) such that C1 != C2 % and for which there is no join C3. % If there exists a join C3 of C1 and C2 then C is a subclass % of C3 (otherwise C should have been declared before C3) % % / --- /-- C1 % C -- no C3 != % \ --- \-- C2 % % [findall-newjoins C AllSuper] finds all C1 and C2 such that C is a (new) join for % them pred distinct-pairs-below i:hbclass, i:list hbclass, o:hbclass, o:hbclass. distinct-pairs-below CurrentClass AllSuper C1 C2 :- std.mem AllSuper C1, std.mem AllSuper C2, % no cut until here, since we don't know which C1 and C2 to pick std.do! [ cmp_term C1 C2 lt, C1 = class C1n _ _, C2 = class C2n _ _ , not(sub-class? C1 C2), not(sub-class? C2 C1), if (join C1n C2n C3n) (assert-building-bottom-up CurrentClass C3n C1n C2n, fail) % a join, not a valid pair true, % no join, valid pair ]. pred assert-building-bottom-up i:hbclass, i:classname, i:classname, i:classname. assert-building-bottom-up CurrentClass C3n C1n C2n :- class-def (class C3n X Y), CurrentClass = class CC _ _, if (not (sub-class? CurrentClass (class C3n X Y))) (gref->modname CC 1 "." Before, gref->modname_short C3n "." After, gref->modname_short C1n "." C1nS, gref->modname_short C2n "." C2nS, Msg1 is "- declare structure " ^ Before ^ " before structure " ^ After ^ " if " ^ After ^ " inherits from it;", Msg2 is "- declare an additional structure that inherits from both " ^ C1nS ^ " and " ^ C2nS ^ " and from which " ^ Before ^ " and/or " ^ After ^ " inherit.", coq.error "You must declare the hierarchy bottom-up or add a missing join." "There are two ways out:" Msg1 Msg2) true. func distinct-pairs_pair prop -> pair hbclass hbclass. distinct-pairs_pair (distinct-pairs-below _ _ X Y) (pr X Y). func findall-newjoins hbclass, list hbclass -> list (pair hbclass hbclass). findall-newjoins CurrentClass AllSuper TodoJoins :- std.findall (distinct-pairs-below CurrentClass AllSuper C1_ C2_) JoinOf, std.map JoinOf distinct-pairs_pair TodoJoins. func class-coverage list classname -> coq.gref.set. class-coverage CNL CSet :- std.map CNL classname->mixins CMLLwP, std.map CMLLwP list-w-params_list CMLL, coq.gref.list->set {std.flatten CMLL} CSet. func assert-good-coverage! list mixinname, list classname ->. assert-good-coverage! MLSortedRev CNL :- std.do! [ coq.gref.list->set MLSortedRev MLSet, class-coverage CNL CMLSet, if (not(coq.gref.set.equal MLSet CMLSet)) (coq.gref.set.diff CMLSet MLSet Extra, coq.error "I could not find classes covering exactly mixins:" {std.any->string MLSortedRev} "In particular the covering" CNL "also includes mixins:" {coq.gref.set.elements Extra} "This should never happen, please report a bug.") true ]. %%%%% Coq Database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [get-structure-coercion S1 S2 F] finds the coecion F from the structure S1 to S2 func get-structure-coercion structure, structure -> term. get-structure-coercion S T (global F) :- coq.coercion.db-for (grefclass S) (grefclass T) L, if (L = [pr F _]) true (coq.error "No one step coercion from" S "to" T). func get-structure-sort-projection structure -> term. get-structure-sort-projection (indt S) Proj :- !, coq.env.projections S L, if (L = [some P, _]) true (coq.error "No canonical sort projection for" S), Proj = global (const P). get-structure-sort-projection S _ :- coq.error "get-structure-sort-projection: not a structure" S. func get-structure-class-projection structure -> term. get-structure-class-projection (indt S) T :- !, coq.env.projections S L, if (L = [_, some P]) true (coq.error "No canonical class projection for" S), T = global (const P). get-structure-class-projection S _ :- coq.error "get-structure-class-projection: not a structure" S. func get-constructor gref -> gref. get-constructor (indt R) (indc K) :- !, if (coq.env.indt R _ _ _ _ [K] _) true (coq.error "Not a record" R). get-constructor I _ :- coq.error "get-constructor: not an inductive" I. % finding for locally defined structures func get-cs-structure cs-instance -> structure. get-cs-structure (cs-instance _ _ (const Inst)) Struct :- std.do! [ coq.env.typeof (const Inst) InstTy, coq.prod-tgt->gref InstTy Struct, is-structure Struct, ]. func get-cs-instance cs-instance -> constant. get-cs-instance (cs-instance _ _ (const Inst)) Inst. func has-cs-instance gref, cs-instance ->. has-cs-instance GTy (cs-instance _ (cs-gref GTy) _). func mixin-src->has-mixin-instance prop -> prop. mixin-src->has-mixin-instance (mixin-src (global GR) M I) (has-mixin-instance (cs-gref GR) M IHd) :- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (app [global GR|_] ) M I) (has-mixin-instance (cs-gref GR) M IHd) :- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (prod _ _ _ ) M I) (has-mixin-instance cs-prod M IHd):- term->gref I IHd. mixin-src->has-mixin-instance (mixin-src (sort U) M I) (has-mixin-instance (cs-sort U) M IHd):- term->gref I IHd. % this auxiliary function iterates over the list of arguments of an application, % and create the necessary unify condition for each arguments % and at the end returns the mixin-src clause with all the conditions func mixin-instance-type->mixin-src.aux list term, % list of arguments term, % head of the original application mixinname, % name of mixin term, % instance body list prop % Cond list -> prop. mixin-instance-type->mixin-src.aux [] T M I Cond (mixin-src T M I :- Cond). mixin-instance-type->mixin-src.aux [A|Args] T M I Cond (pi a \ C a) :- pi a \ sigma Ta\ coq.mk-app T [a] Ta, mixin-instance-type->mixin-src.aux Args Ta M I [coq.unify-eq A a ok|Cond] (C a). % transforms the type of a mixin instance into a % mixin-src clause with eventual conditions regarding its parameters :index (1) func mixin-instance-type->mixin-src term, % type of the instance Ty mixinname, % name of mixin term, % instance body I of type Ty list prop % Cond list -> prop. mixin-instance-type->mixin-src (app _ as F) M I Cond C :- factory? F (triple _ _ Subject), safe-dest-app Subject Hd Args, mixin-instance-type->mixin-src.aux Args Hd M I Cond C. mixin-instance-type->mixin-src (prod N_ _ F) M I Cond (pi a \ C a) :- pi a\ sigma Ia \ coq.mk-app I [a] Ia, mixin-instance-type->mixin-src (F a) M Ia Cond (C a). func has-mixin-instance->mixin-src prop -> prop. has-mixin-instance->mixin-src (has-mixin-instance _ M IHd) C :- std.do![ T = global IHd, coq.env.typeof IHd Ty, mixin-instance-type->mixin-src Ty M T [] C, ]. func get-canonical-structures term -> list structure. get-canonical-structures TyTrm StructL :- std.do! [ term->cs-pattern TyTrm Pat, !, coq.CS.db-for _ Pat DBGTyL, std.map-filter DBGTyL get-cs-structure StructL, ]. func get-canonical-instances term -> list constant. get-canonical-instances TyTrm StructL :- term->cs-pattern TyTrm Pat, coq.CS.db-for _ Pat DBGTyL, std.map-filter DBGTyL get-cs-instance StructL. func has-CS-instance? term, structure ->. has-CS-instance? TyTerm (indt Struct) :- term->cs-pattern TyTerm Pat, coq.env.projections Struct [some Proj, _], coq.CS.db-for (const Proj) Pat L, not(L = []). pred structure-nparams i:structure, o:int. structure-nparams Structure NParams :- class-def (class Class Structure _), factory->nparams Class NParams. func factory? term -> w-args factoryname. factory? S (triple F Params T) :- not (var S), !, safe-dest-app S (global GR) Args, factory-alias->gref GR F ok, factory->nparams F NP, !, std.split-at NP Args Params [T|_]. % [find-max-classes Mixins Classes] states that Classes is a list of classes % which contain all the mixins in Mixins. % Although it is not strictly necessary, but desirable for debugging, % we use a heuristic that tries to minimize the number % of classes by assuming Mixins are reversed topologically sorted. % Note: works with flat mixins, no params pred find-max-classes i:list mixinname, o:list classname. find-max-classes [] []. find-max-classes [M|Mixins] [C|Classes] :- mixin->first-class M C, std.do! [ class-def (class C _ MLwP), list-w-params_list MLwP ML, std.filter Mixins (x\ not (std.mem! ML x)) Mixins', find-max-classes Mixins' Classes ]. find-max-classes [M|_] _ :- coq.error "HB: cannot find a class containing mixin" M. math-comp-hierarchy-builder-4d8a939/HB/common/log.elpi000066400000000000000000000463601521677141400226040ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains proxies for the API to write into the Coq state (eg add % an inductive, set implicit arguments...). This has two purposes: % - give nicer error messages % - we want to be able to log to a file all these actions (WIP), this file is % were logging takes place. Hence we never call, say, coq.evn.add-* directly, % but always via this proxy namespace log.coq { :index (1) func arguments.set-implicit gref, list (list implicit_kind). arguments.set-implicit GR I :- coq.arguments.set-implicit GR I, if (@local!) (Local = tt) (Local = ff), log.private.log-vernac (log.private.coq.vernac.implicit Local {coq.gref->id GR} I). func env.add-location gref ->. env.add-location GR :- if (get-option "elpi.loc" Loc) % remove when coq-elpi > 1.9 (acc-clause library (decl-location GR Loc)) true. func strategy.set list constant, conversion_strategy ->. strategy.set CL S :- coq.strategy.set CL S, log.private.log-vernac (log.private.coq.vernac.strategy CL S). :index (1) func env.add-const-noimplicits id, term, term, opaque? -> constant. env.add-const-noimplicits Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, avoid-name-collision Name Name1, coq.env.add-const Name1 Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name1 Ty? Bo), @local! => arguments.set-implicit (const C) [[]], ]. :index (1) func env.add-const id, term, term, opaque? -> constant. env.add-const Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, avoid-name-collision Name Name1, coq.env.add-const Name1 Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name1 Ty? Bo), ]. func env.add-const-noimplicits-failondup id, term, term, opaque? -> constant. env.add-const-noimplicits-failondup Name Bo Ty Opaque C :- std.do! [ if (not(ground_term Ty ; ground_term Bo)) (coq.error "HB: cannot infer some information in" Name ":" {coq.term->string Ty} ":=" {coq.term->string Bo}) true, coq.env.add-const Name Bo Ty Opaque C, env.add-location (const C), if (var Ty) (Ty? = none) (Ty? = some Ty), log.private.log-vernac (log.private.coq.vernac.definition Name Ty? Bo), @local! => arguments.set-implicit (const C) [[]], ]. func env.add-parameter id, term -> constant. env.add-parameter ID Ty C :- std.do! [ @global! => coq.env.add-axiom ID Ty C, log.private.log-vernac (log.private.coq.vernac.parameter ID Ty), ]. func env.add-indt indt-decl -> inductive. env.add-indt Decl I :- std.do! [ if (not(coq.ground-indt-decl? Decl)) (coq.error "HB: cannot infer some information in" {coq.indt-decl->string Decl}) true, coq.env.add-indt Decl I, (coq.env.record? I P ; P = ff), log.private.log-vernac (log.private.coq.vernac.inductive Decl P), env.add-location (indt I), % copy the current value of implicit arguments coq.env.indt I _ _ _ _ KS _, log.private.log-implicits-of ff (indt I), std.forall KS (k\ env.add-location (indc k), log.private.log-implicits-of ff (indc k)), std.forall {coq.env.projections I} (p\ sigma c\ if (p = some c) (env.add-location (const c), log.private.log-implicits-of ff (const c)) true), ]. :index (_ 1) func env.begin-module id, option (pair modtypath id) . env.begin-module Name none :- coq.env.begin-module Name none, log.private.log-vernac (log.private.coq.vernac.begin-module Name none). env.begin-module Name (some (pr Sig SigName)) :- std.do! [ coq.env.begin-module Name (some Sig), log.private.log-vernac (log.private.coq.vernac.begin-module Name (some SigName)), ]. func env.begin-module-type id ->. env.begin-module-type Name :- std.do! [ coq.env.begin-module-type Name, log.private.log-vernac (log.private.coq.vernac.begin-module-type Name), ]. func env.end-module-name id -> modpath. env.end-module-name Name M :- coq.env.end-module M, log.private.log-vernac (log.private.coq.vernac.end-module Name). func env.end-module-type-name id -> modtypath. env.end-module-type-name Name M :- std.do! [ coq.env.end-module-type M, log.private.log-vernac (log.private.coq.vernac.end-module-type Name), ]. func env.begin-section id ->. env.begin-section Name :- std.do! [ coq.env.begin-section Name, log.private.log-vernac (log.private.coq.vernac.begin-section Name), ]. func env.end-section-name id. env.end-section-name Name :- std.do! [ coq.env.end-section, log.private.log-vernac (log.private.coq.vernac.end-section Name), ]. func notation.add-abbreviation id, int, term, bool -> abbreviation. notation.add-abbreviation Name NArgs Body OnlyParsing O :- coq.notation.add-abbreviation Name NArgs Body OnlyParsing O, log.private.log-vernac (log.private.coq.vernac.abbreviation Name NArgs Body). func env.export-module id, modpath ->. env.export-module MPNice M :- std.do! [ coq.env.export-module M, log.private.log-vernac (log.private.coq.vernac.export-module MPNice), ]. func env.import-module id, modpath ->. env.import-module MPNice M :- std.do! [ coq.env.import-module M, log.private.log-vernac (log.private.coq.vernac.import-module MPNice), ]. func coercion.declare coercion -> . coercion.declare C :- std.do! [ @global! => @reversible! => coq.coercion.declare C, C = coercion GR _ SRCGR TGTCL, coq.gref->id GR Name, log.private.log-vernac (log.private.coq.vernac.coercion Name SRCGR TGTCL), ]. } % Since CS.foo is not a valid predicate name we can't use it % in the namespace, so we just define it here with the full name func log.coq.CS.declare-instance constant ->. log.coq.CS.declare-instance C :- std.do! [ if (@local!) (Local = tt) (Local = ff), coq.CS.declare-instance (const C), coq.gref->id (const C) Id, std.last {coq.gref->path (const C)} M, std.last {coq.env.current-path} M1, if (M = M1) (Name = Id) (Name is M ^ "." ^ Id), log.private.log-vernac (log.private.coq.vernac.canonical Name Local), ]. func log.coq.check term -> term, term, diagnostic. log.coq.check Skel Ty T D :- std.do! [ coq.elaborate-skeleton Skel Ty T D, if (get-option "fail" tt) (Fail = tt) (Fail = ff), log.private.log-vernac (log.private.coq.vernac.check Skel Fail), ]. func refine term, goal -> list sealed-goal. % to silence a warning, since this is only in tactics func log.refine term, goal -> list sealed-goal. log.refine T G GL :- std.do! [ refine T G GL, G = goal _ _ _ Solution _, log.private.log-tactic Solution, ]. func refine.no_check term, goal -> list sealed-goal. % to silence a warning, since this is only in tactics func log.refine.no_check term, goal -> list sealed-goal. log.refine.no_check T G GL :- std.do! [ refine.no_check T G GL, G = goal _ _ _ Solution _, log.private.log-tactic Solution, ]. namespace log.private { %%%%% Logging Utils %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func log-implicits-of bool, gref -> . log-implicits-of Local GR :- coq.arguments.implicit GR I, if (std.forall I (i\ std.forall i (x\ x = explicit))) (IMP = [[]]) (IMP = I), log.private.log-vernac (log.private.coq.vernac.implicit Local {coq.gref->id GR} IMP). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Coq document % This is a very minimalistic AST to represent a Coq document equipped with % pretty printing facilities. % % When "complete enough" this should be moved to coq-elpi proper. kind coq.vernac type. type coq.vernac.begin-module string -> option string -> coq.vernac. type coq.vernac.end-module string -> coq.vernac. type coq.vernac.begin-module-type string -> coq.vernac. type coq.vernac.end-module-type string -> coq.vernac. type coq.vernac.begin-section string -> coq.vernac. type coq.vernac.end-section string -> coq.vernac. type coq.vernac.import-module string -> coq.vernac. type coq.vernac.export-module string -> coq.vernac. type coq.vernac.definition string -> option term -> term -> coq.vernac. type coq.vernac.variable string -> term -> coq.vernac. type coq.vernac.parameter string -> term -> coq.vernac. type coq.vernac.inductive indt-decl -> bool -> coq.vernac. type coq.vernac.abbreviation string -> int -> term -> coq.vernac. type coq.vernac.notation string -> int -> term -> coq.vernac. type coq.vernac.coercion string -> gref -> class -> coq.vernac. type coq.vernac.canonical string -> bool -> coq.vernac. type coq.vernac.implicit bool -> string -> list (list implicit_kind) -> coq.vernac. type coq.vernac.comment A -> coq.vernac. type coq.vernac.check term -> bool -> coq.vernac. type coq.vernac.strategy list constant -> conversion_strategy -> coq.vernac. } func with-logging (func) ->. func log.private.log-vernac log.private.coq.vernac ->. func log.private.log-tactic term ->. /* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % implementation of logging and vernac printing with-logging P :- (get-option "elpi.hb.log" _, NICE = tt ; get-option "elpi.hb.log.raw" _, NICE = ff), !, get-option "elpi.loc" Loc, !, loc.fields Loc FILE Start Stop _ _, LocStr is "characters " ^ {std.any->string Start} ^ "-" ^ {std.any->string Stop}, FILENAME is FILE ^ ".hb", open_append FILENAME OC1, std.string.concat "\n" ["","HIERARCHY BUILDER PATCH v1",LocStr,""] PATCH1, output OC1 PATCH1, close_out OC1, (log.private.logger L NICE => P), log.private.logger-close L, std.intersperse coq.pp.spc L PP, coq.pp->string (coq.pp.box (coq.pp.v 0) PP) S, open_append FILENAME OC2, output OC2 S, close_out OC2. with-logging P :- (get-option "log" tt, NICE = tt ; get-option "log.raw" tt, NICE = ff), !, (log.private.logger L NICE => P), log.private.logger-close L, std.intersperse coq.pp.spc L PP, coq.pp->string (coq.pp.box (coq.pp.v 0) PP) S, coq.say "(* \n" S "\n*)". with-logging P :- P. log.private.log-vernac V :- log.private.logger L Nice, !, if (Nice = tt) (PPALL = []) (PPALL = [@ppall!]), log.private.logger-extend L {PPALL => log.private.coq.vernac->pp [V]}. log.private.log-vernac _. log.private.log-tactic P :- log.private.logger L Nice, !, if (Nice = tt) (PPALL = []) (PPALL = [@ppall!]), log.private.logger-extend L {PPALL => @holes! => coq.term->pp P}. log.private.log-tactic _. % The main entry point to print vernacular commands is coq.vernac->pp shorten log.private.coq.vernac.{ begin-module , end-module , begin-section, end-section }. shorten log.private.coq.vernac.{ begin-module-type , end-module-type }. shorten log.private.coq.vernac.{ import-module , export-module }. shorten log.private.coq.vernac.{ definition , variable , comment , check }. shorten log.private.coq.{ vernac.inductive , vernac.implicit , vernac.parameter }. shorten log.private.coq.vernac.{ canonical , abbreviation , notation , coercion , strategy }. shorten log.private.{ coq.vernac }. shorten coq.pp.{ box , h , spc , v , str , hv , hov, glue, brk }. namespace log.private { pred logger o:list coq.pp, o:bool. :index (1) func logger-extend list coq.pp, coq.pp ->. logger-extend [] _ :- coq.error "HB: logger was closed". logger-extend (uvar as X) V :- X = [V|FRESH_]. logger-extend [_|XS] V :- logger-extend XS V. func logger-close list coq.pp ->. logger-close (uvar as X) :- X = []. logger-close [_|XS] :- logger-close XS. func coq.vernac->pp list coq.vernac -> coq.pp. coq.vernac->pp L (box (v 0) L2) :- std.map L coq.vernac->pp1 L1, std.intersperse spc L1 L2. func coq.vernac->pp1 coq.vernac -> coq.pp. coq.vernac->pp1 (begin-module Name none) PP :- PP = box h [str "Module ", str Name, str "."]. coq.vernac->pp1 (begin-module Name (some TyName)) PP :- PP = box h [str "Module ", str Name, str " : ", str TyName, str "."]. coq.vernac->pp1 (end-module Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (begin-module-type Name) PP :- PP = box h [str "Module Type ", str Name, str "."]. coq.vernac->pp1 (end-module-type Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (begin-section Name) PP :- PP = box h [str "Section ", str Name, str "."]. coq.vernac->pp1 (end-section Name) PP :- PP = box h [str "End ", str Name, str "."]. coq.vernac->pp1 (definition Name none Body) PP :- PP = box (hv 2) [str "Definition ", str Name, str " :=", spc, B, str "."], coq.term->pp Body B. coq.vernac->pp1 (definition Name (some Ty) Body) PP :- PP = box (hv 2) [str "Definition ", str Name, str " : ", T, str " :=", spc, B, str "."], coq.term->pp Ty T, coq.term->pp Body B. coq.vernac->pp1 (variable Name Ty) (box (hv 2) [box h [str "Variable ", str Name, str " :"], spc, TY, str "."]) :- coq.term->pp Ty TY. coq.vernac->pp1 (vernac.parameter Name Ty) (box (hv 2) [box h [str "Parameter ", str Name, str " :"], spc, TY, str "."]) :- coq.term->pp Ty TY. coq.vernac->pp1 (import-module Name) (box h [str "Import ", str Name, str "."]). coq.vernac->pp1 (export-module Name) (box h [str "Export ", str Name, str "."]). coq.vernac->pp1 (notation KM NParams Term) (box (hv 2) [box h [str "Notation \"'",str KM,str"' "|StrParams], str "\" := (", spc, B, str ") (at level 1)."]) :- !, coq.vernac->ppabbrterm NParams Term StrParams B. coq.vernac->pp1 (abbreviation Name NParams Term) (box (hv 2) [box h [str "Notation ",str Name|StrParams], str " := (", spc, B, str ")."]) :- coq.vernac->ppabbrterm NParams Term StrParams B. coq.vernac->pp1 (canonical Name Local) (box h [Locality, str "Canonical ", str Name, str "."]) :- local->locality Local Locality. coq.vernac->pp1 (coercion Name SRC TGT) (box h [str "#[reversible] Coercion ", str Name, str " : ", str S, str " >-> ", str T, str "."]) :- coq.gref->path SRC SP, std.string.concat "." {std.take-last 2 SP} S', S is S' ^ "." ^ {coq.gref->id SRC}, if2 (TGT = sortclass) (T = "Sortclass") (TGT = funclass) (T = "Funclass") (TGT = grefclass GR, coq.gref->path GR GRP, std.string.concat "." {std.take-last 2 GRP} T', T is T' ^ "." ^ {coq.gref->id GR}). coq.vernac->pp1 (vernac.inductive I Primitive) (glue [str Start, PP, str Stop]) :- coq.vernac->ppinductive I [] PP, if (Primitive = tt) (Start = "Set Primitive Projections. ", Stop = "Unset Primitive Projections. ") (Start = "", Stop = ""). coq.vernac->pp1 (vernac.implicit Local Name [[]]) (box h [Locality, str "Arguments ", str Name, str " : clear implicits."]) :- !, local->locality Local Locality. coq.vernac->pp1 (vernac.implicit Local Name [L]) (box h [Locality, str "Arguments ", str Name, spc, glue PP, str "."]) :- local->locality Local Locality, std.map L coq.vernac->ppimparg PP1, std.intersperse spc PP1 PP. coq.vernac->pp1 (comment A) (box (hov 2) [str"(*", str S, str"*)"]) :- std.any->string A S. coq.vernac->pp1 (check T Fail) (box (hov 2) [Failure, str"Check", spc, PPT, str"."]) :- (@holes! => coq.term->pp T PPT), fail->failure Fail Failure. coq.vernac->pp1 (strategy L opaque) (box (hov 2) [str"Strategy opaque [", glue PPL , str"]."]) :- std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. coq.vernac->pp1 (strategy L expand) (box (hov 2) [str"Strategy expand [", glue PPL , str"]."]) :- std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. coq.vernac->pp1 (strategy L (level N)) (box (hov 2) [str"Strategy ",str NPP,str" [", glue PPL , str"]."]) :- std.any->string N NPP, std.map L (c\r\sigma id\coq.gref->id (const c) id, r = str id) LID, std.intersperse spc LID PPL. func local->locality bool -> coq.pp. local->locality tt (str "Local "). local->locality ff (str "Global "). func fail->failure bool -> coq.pp. fail->failure tt (str "Fail "). fail->failure ff (str ""). func coq.vernac->ppimparg implicit_kind -> coq.pp. coq.vernac->ppimparg explicit (str "_"). coq.vernac->ppimparg maximal (str "{_}"). coq.vernac->ppimparg implicit (str "[_]"). :index (3) func coq.vernac->ppinductive indt-decl, list (pair implicit_kind term) -> coq.pp. coq.vernac->ppinductive (parameter ID IMPL TY I) Acc R :- @pi-parameter ID TY p\ coq.vernac->ppinductive (I p) [pr IMPL p|Acc] R. coq.vernac->ppinductive (record ID SORT KID RD) ParamsRev (box (v 0) [Hack1, PP, Hack2]) :- PP = (box (hov 0) [ box (hov 0) [str "Record", spc, str ID, brk 1 4, glue ParamsPP, str " : ", SortPP, brk 1 2, str":= ", str KID], brk 1 2, box (hv 2) [str"{", spc, glue FieldsPP, str"}"], str"."]), Hack1 = glue [str "Section ", str ID, str ".", spc, str "Local Unset Implicit Arguments.", spc], Hack2 = glue [spc, str "End ", str ID, str".", spc], std.rev ParamsRev Params, coq.vernac->ppinductiveparams Params ParamsPP, coq.term->pp SORT SortPP, coq.vernac->pprecordfields RD FieldsPP. coq.vernac->ppinductive (inductive ID IsInd Arity Ks) ParamsRev PP :- PP = (box (hov 0) [ str CO,str "Inductive", spc, box (hov 0) [ str ID, brk 1 4, glue ParamsPP, ArityPP, str " :="], brk 0 2, box (hv 2) [str" ", glue KsPp], str "."]), std.rev ParamsRev Params, coq.vernac->ppinductiveparams Params ParamsPP, std.map Params snd ParamsAsArgs, if (IsInd = tt) (CO = "") (CO = "Co"), coq.arity->pp Arity ArityPP, @pi-inductive ID Arity x\ coq.mk-app x ParamsAsArgs (X x), coq.vernac->ppinductiveconstructor (Ks (X x)) KsPp. func coq.vernac->ppinductiveconstructor list indc-decl -> list coq.pp. coq.vernac->ppinductiveconstructor [] []. coq.vernac->ppinductiveconstructor [constructor ID Arity|Ks] PP :- PP = [str ID,{coq.arity->pp Arity},SEP|Rest], if (Ks = []) (SEP = str"") (SEP = glue [brk 1 0, str "| "]), coq.vernac->ppinductiveconstructor Ks Rest. func coq.vernac->ppinductiveparams list (pair implicit_kind term) -> list coq.pp. coq.vernac->ppinductiveparams [] []. coq.vernac->ppinductiveparams [pr Imp T|Rest] PP :- PP = [box (hov 2) [str A,ID,str " : ", TY,str B]|PPRest], coq.term->pp T ID, decl T _ Ty, coq.term->pp Ty TY, if2 (Imp = explicit) (A = "(", B = ")") (Imp = maximal) (A = "{", B = "}") (A = "[", B = "]"), coq.vernac->ppinductiveparams Rest PPRest. func coq.vernac->pprecordfields record-decl -> list coq.pp. coq.vernac->pprecordfields end-record []. coq.vernac->pprecordfields (field _ ID TY F) [ str ID, str " : ", TYPP, str ";", spc|FPP] :- % TODO attributes coq.term->pp TY TYPP, @pi-parameter ID TY p\ coq.vernac->pprecordfields (F p) FPP. :index (1 1) func coq.vernac->ppabbrterm int, term -> list coq.pp, coq.pp. coq.vernac->ppabbrterm 0 T [] B :- !, @holes! => coq.term->pp T B. coq.vernac->ppabbrterm N (fun _ _ F) [spc,str ID|StrParams] B :- ID is "X" ^ {std.any->string N}, coq.id->name ID Name, M is N - 1, @pi-decl Name (sort prop) x\ coq.vernac->ppabbrterm M (F x) StrParams B. } math-comp-hierarchy-builder-4d8a939/HB/common/phant-abbreviation.elpi000066400000000000000000000322721521677141400255750ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % Kit to build abbreviations /à la/ *pack*, that is % [Notation N x_0 .. x_n := C x_0 .. _ _ id .. x_i .. _ id _ _ id] % with a variable number of [_] between each [id], and where % - [x_i] is given by the user % - [_] correspond to arguments that are left implicit, % - [id] trigger unification as described in % - [Phant x] to infer the canonical structure on x % % See /Canonical Structures for the working Coq user/ by Mahboubi and Tassi % This type is private, build it via the APIs below typeabbrev phant-term phant.private.phant-term. namespace phant { % [add-abbreviation Name PhT C A] builds a definition "phant_Name" for the % term T and an abbreviation Name as per Ph. % Use the API below to build a PhT as you like. func add-abbreviation string, phant-term -> constant, abbreviation. add-abbreviation N (private.phant-term AL T1) C Abbrev :- std.do! [ NC is "phant_" ^ N, std.assert-ok! (coq.elaborate-skeleton T1 TTy T) "add-abbreviation: T illtyped", log.coq.env.add-const-noimplicits NC T TTy @transparent! C, private.build-abbreviation 0 (global (const C)) AL NParams AbbrevT, @global! => log.coq.notation.add-abbreviation N NParams AbbrevT tt Abbrev, ]. % [of-gref WithCopy GR RealMixinArgs PT] % builds a phant-term taking all parameters, % the type, then inferring automatically all structures covering the mixins % GR depends on. RealMixinArgs is a list of mixins one wants to explicitly % pass (instead of being inferred) % If WithCopy = tt, an extra argument is added after all the parameters % and before the source keu to replace the target key by a user chosen one. func of-gref bool, gref, list mixinname -> phant-term. of-gref WithCopy GRF RealMixinArgs PhBody:- !, std.do! [ std.assert! (gref->deps GRF MLwP) "mk-phant-term: unknown gref", std.assert! (coq.env.typeof GRF FTy) "mk-phant-term: F illtyped", coq.mk-eta (-1) FTy (global GRF) EtaF, % toposort-mixins ML MLSorted, MLwP = MLwPSorted, % Assumes we give them already sorted in dep order. std.rev {list-w-params_list MLwPSorted} MLSortedRev, std.map RealMixinArgs (m\ r\ r = private.this-mixin-is-real-arg m) RMClauses, std.filter MLSortedRev (m\ not(std.mem! RealMixinArgs m)) MLSortedRevFiltered, find-max-classes MLSortedRevFiltered CNL, assert-good-coverage! MLSortedRevFiltered CNL, RMClauses => if (WithCopy = ff) (w-params.then MLwP fun-real fun-real (ps\ t\ ml\ o\ private.mk-phant-term.classes EtaF CNL ps t t ml o) PhBody) (w-params.fold MLwP fun-real (private.mk-phant-term-with-copy EtaF CNL) PhBody ) ]. % API à la carte: start with a term and wrap it up ------------------------- % A term with no phantom arguments func init term -> phant-term. init T (private.phant-term [] T). % [fun-real N T Ph Ph1] Adds a real argument named N of type T around Ph func fun-real name, term, (term -> phant-term) -> phant-term. fun-real N T F Res :- !, private.phant-fun (private.real N) T F Res. % [fun-unify Msg X1 X2 Ph Ph1] Adds an argument that will foce the unification % of X1 with X2 and print Msg is case of error around Ph func fun-unify option term, term, term, phant-term -> phant-term. fun-unify OMsg X1 X2 (private.phant-term AL F) (private.phant-term [private.unify|AL] UF) :- std.assert-ok! (coq.typecheck X1 T1) "fun-unify: X1 illtyped", std.assert-ok! (coq.typecheck X2 T2) "fun-unify: X2 illtyped", if (OMsg = some M) (Msg = {{lib:hb.not_a_msg lp:M}}) (Msg = {{lib:hb.nomsg}}), UF = {{fun unif_arbitrary : lib:hb.unify lp:T1 lp:T2 lp:X1 lp:X2 lp:Msg => lp:F}}. % [fun-implicit N T Ph Ph1] Adds an implicit argument name N of type T areound Ph func fun-implicit name, term, (term -> phant-term) -> phant-term. fun-implicit N Ty (t\ private.phant-term AL (F t)) (private.phant-term [private.implicit|AL] (fun N Ty F)). % [fun-infer-type N T Ph Ph1] Adds an argument N of type T such that one passes % a value V of type {{ Type }} the corresponding canonical VC of type T is passed % for N , eg `fun T (phT : phant T) => Ph` func fun-infer-type class, name, term, (term -> phant-term) -> phant-term. fun-infer-type sortclass N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, fun-implicit N Ty (t\private.phant-term [private.infer-type N sortclass|AL] (fun PhN {{ lib:@hb.phant lp:t }} _\ Bo t)) Out. fun-infer-type funclass N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, fun-implicit N Ty (t\private.phant-term [private.infer-type N funclass|AL] (fun PhN {{ lib:@hb.phantom (_ -> _) lp:t }} _\ Bo t)) Out. fun-infer-type (grefclass Class) N Ty (t\private.phant-term AL (Bo t)) Out :- coq.name-suffix N "ph" PhN, private.build-type-pattern Class Pat, fun-implicit N Ty (t\private.phant-term [private.infer-type N (grefclass Class)|AL] (fun PhN {{ lib:@hb.phantom lp:Pat lp:t }} _\ Bo t)) Out. % TODO: this looks like a hack to remove func append-fun-unify phant-term -> phant-term. append-fun-unify (private.phant-term LP T) (private.phant-term LPU T) :- std.append LP [private.unify] LPU. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % phant-term is a pair of a list of argument kinds together with a term kind phant-term type. type phant-term list phant-arg -> term -> phant-term. % phant-arg encode these three kind of arguments % - [x_i] is encoded using [real x_i] % - [_] using [implicit] % - [id] using [unify] % - [Phant x] using [infer-type] kind phant-arg type. type real name -> phant-arg. type infer-type name -> class -> phant-arg. type implicit phant-arg. type unify phant-arg. shorten coq.{ mk-app }. pred this-mixin-is-real-arg o:mixinname. func phant-fun phant-arg, term, (term -> phant-term) -> phant-term. phant-fun Arg Ty PhF (phant-term [Arg|ArgL] (fun N Ty F)) :- if (Arg = real N) true (N = `_`), @pi-decl N Ty x\ PhF x = phant-term ArgL (F x). % [phant-fun-mixin N Ty PF PUF] states that PUF is a phant-term % which quantifies [PF x] over [x : Ty] (with name N) % Ty must be an (applied) mixin M, and the phantom status of this mixin % is determined by [this-mixin-is-real-arg M]. func phant-fun-mixin name, term, (term -> phant-term) -> phant-term. phant-fun-mixin N Ty PF (private.phant-term [Status|AL] (fun N Ty F)) :- !, std.do! [ @pi-decl N Ty t\ PF t = private.phant-term AL (F t), coq.safe-dest-app Ty (global Mixin) _, if (this-mixin-is-real-arg Mixin) (Status = private.real N) (Status = private.implicit) ]. func fun-unify-mixin term, name, term, (term -> phant-term) -> phant-term. fun-unify-mixin T N Ty PF Out :- !, std.do! [ coq.safe-dest-app Ty (global M) _, Msg is "fun-unify-mixin: No mixin-src on " ^ {coq.term->string T}, std.assert! (mixin-src T M Msrc) Msg, (@pi-decl `m` Ty m\ fun-unify none m Msrc (PF m) (PFM m)), fun-implicit N Ty PFM Out ]. % [phant-fun-struct T S Params PF PSF] states that PSF is a phant-term % which postulate a structure [s : S Params] such that [T = sort s] % and then outputs [PF s] func phant-fun-struct term, name, structure, list term, (term -> phant-term) -> phant-term. phant-fun-struct T Name S Params PF Out :- std.do! [ get-structure-sort-projection S SortProj, mk-app (global S) Params SParams, mk-app SortProj Params SortProjParams, % Msg = {{lib:hb.nomsg}}, Msg = some {{lp:SParams}}, (@pi-decl Name SParams s\ fun-unify Msg T {mk-app SortProjParams [s]} (PF s) (UnifSI s)), fun-implicit Name SParams UnifSI Out ]. % A *pack* notation can be easiliy produced from a phant-term using % [add-abbreviation N PT C], which states that C is a new constant % which name is phant_N, and which produces a simple notation % with name N using the data of the phant-term PT to reconstruct a notation % [Notation N x0 .. xn := C x0 _ _ id .. xi .. _ id _ _ id] % as described above. func build-abbreviation int, term, list phant-arg -> int, term. build-abbreviation K F [] K F. build-abbreviation K F [real N|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [x]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N sortclass|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phant lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N funclass|AL] K'' (fun N _ AbbrevFx) :- !, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phantom (_ -> _) lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [infer-type N (grefclass Class)|AL] K'' (fun N _ AbbrevFx) :- !, build-type-pattern Class Pat, pi x\ build-abbreviation K {mk-app F [{{ lib:hb.Phantom lp:Pat lp:x }}]} AL K' (AbbrevFx x), K'' is K' + 1. build-abbreviation K F [implicit|AL] K' FAbbrev :- !, build-abbreviation K {mk-app F [_]} AL K' FAbbrev. build-abbreviation K F [unify|AL] K' FAbbrev :- !, build-abbreviation K {mk-app F [{{lib:@hb.id _ _}}]} AL K' FAbbrev. % [build-type-pattern GR Pat] cheks that GR : forall x_1 ... x_n, Type % and returns Pat = GR _ ... _ (that is GR applied to n holes). % Note that n can be 0 when GR : Type. func build-type-pattern gref -> term. build-type-pattern GR Pat :- build-type-pattern.aux GR {coq.env.typeof GR} Pat. func build-type-pattern.aux gref, term -> term. build-type-pattern.aux GR T {{ lp:Pat _ }} :- coq.unify-eq T (prod N S T') ok, !, @pi-decl N S x\ build-type-pattern.aux GR (T' x) Pat. build-type-pattern.aux GR T (global GR) :- coq.unify-eq T {{ Type }} ok, !. build-type-pattern.aux _ _ _ :- coq.error "HB: wrong carrier type". % [mk-phant-term F PF] states that % if F = fun p1 .. p_k T m_0 .. m_n => _ % then PF = phant-term % [real p_1, ... real p_k, real T, implicit, .., implicit, % implicit, .., implicit, % implicit, unify, % implicit, unify, % implicit, .., implicit, unify, % unify, ..., unify, % ..., % implicit, .., implicit, % implicit, unify, % implicit, unify, % implicit, .., implicit, unify, % unify, ..., unify] % {{fun p_1 ... p_k T m_0 .. m_n => % fun q_1 .. q_l => % [find t | T ~ t] % [find s_0 | t ~ s_0] % [find c_0 | s_0 ~ SK q_1 .. q_l t c_0] % [find m'_{i_0_0}, .., m'_{i_0_n0} | c_0 ~ CK m'_{i_0_0} .. m'_{i_0_n0}] % fun & hb.unify m_{i_0_0} m'_{i_0_0} & ... & hb.unify m_{i_0_n0} m'_{i_0_n0} => % ... % fun q'_1 .. q'_l' => % [find t | T ~ t] % [find s_k | t ~ s_k] % [find c_k | s_k ~ SK q'_1 .. q'_l' y c_k] % [find m'_{i_k_0}, .., m'_{i_k_nk} | c_0 ~ CK m'_{i_k_0} .. m'_{i_k_nk}] % fun & hb.unify m_{i_0_0} m'_{i_0_0} & ... & hb.unify m_{i_k_nk} m'_{i_k_nk} => % F p_1 ... p_k T m_i0_j0 .. m_il_jl}} func mk-phant-term.mixins term, term, classname, phant-term, list term, name, term, (term -> list (w-args mixinname)) -> phant-term. mk-phant-term.mixins Target Src CN PF Params N Ty MLwA Out :- std.do! [ class-def (class CN SI _), mk-app (global SI) Params SIParams, coq.name-suffix N "local" Nlocal, (@pi-decl Nlocal Ty t\ sigma SK KC ML ParamsT SKPT\ std.do! [ std.map (MLwA t) triple_1 ML, std.append Params [t] ParamsT, SKPT = app [global {get-constructor SI} | ParamsT], ClassTy t = app [global CN | ParamsT], (@pi-decl `s` SIParams s\ @pi-decl `c` (ClassTy t) c\ sigma PF2\ std.do![ synthesis.under-mixins.then (MLwA t) (fun-unify-mixin Target) (mk-phant-term.mixins.aux t Params c CN PF) PF2, fun-unify none s {mk-app SKPT [c]} PF2 (PFU t s c), ]), Body t = {fun-unify none t Src {phant-fun-struct t `s` SI Params s\ {fun-implicit `c` (ClassTy t) (PFU t s)}}} ]), fun-implicit Nlocal Ty Body Out ]. mk-phant-term.mixins.aux T Params C CN PF X :- std.do![ get-constructor CN KC, synthesis.infer-all-gref->deps Params T KC KCM, fun-unify none KCM C PF X, ]. func mk-phant-term.class term, term, classname, phant-term -> phant-term. mk-phant-term.class Target Src CN PF CPF :- !, std.do! [ class-def (class CN _ CMLwP), w-params.fold CMLwP fun-implicit (mk-phant-term.mixins Target Src CN PF) CPF, ]. func mk-phant-term.classes term, list classname, list term, term, term, list (w-args mixinname) -> phant-term. mk-phant-term.classes EtaF CNF PL Target Src MLwA PhF :- !, std.do! [ std.map MLwA triple_1 ML, synthesis.under-mixins.then MLwA phant-fun-mixin (out\ sigma FPLTM\ std.do! [ synthesis.infer-all-these-mixin-args PL Target ML EtaF FPLTM, std.fold CNF (phant-term [] FPLTM) (mk-phant-term.class Target Src) out]) PhF ]. func mk-phant-term-with-copy term, list classname, list term, name, term, (term -> list (w-args mixinname)) -> phant-term. mk-phant-term-with-copy EtaF CNF PL N Ty MLwA PhF :- !, std.do! [ (@pi-decl N Ty target\ @pi-decl N Ty src\ sigma Body\ mk-phant-term.classes EtaF CNF PL target src (MLwA target) Body, fun-unify none target src Body (BodyUnif target src)), fun-real N Ty (target\ {fun-real N Ty (BodyUnif target)}) PhF ]. }} math-comp-hierarchy-builder-4d8a939/HB/common/stdpp.elpi000066400000000000000000000334731521677141400231560ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains additions to elpi or coq-elpi standard library % elpi:if version < 2.0.0 kind triple type -> type -> type -> type. type triple A -> B -> C -> triple A B C. func triple_1 triple A B C -> A. triple_1 (triple A _ _) A. func triple_2 triple A B C -> B. triple_2 (triple _ B _) B. func triple_3 triple A B C -> C. triple_3 (triple _ _ C) C. % elpi:endif namespace std { func nlist int, A -> list A. nlist N X L :- std.map {std.iota N} (_\ y\ y = X) L. :index (_ 1) func list-diff list A, list A -> list A. list-diff X [] X. list-diff L [D|DS] R :- std.filter L (x\ not(x = D)) L1, list-diff L1 DS R. func list-uniq list A -> list A. pred list-uniq.seen i:A. list-uniq [] []. list-uniq [X|XS] YS :- list-uniq.seen X, !, list-uniq XS YS. list-uniq [X|XS] [X|YS] :- list-uniq.seen X => list-uniq XS YS. func list-eq-set list A, list A. list-eq-set L1 L2 :- list-diff L1 L2 [], list-diff L2 L1 []. pred under.do! i:((A -> prop) -> A -> prop), i:list prop. under.do! Then LP :- Then (_\ std.do! LP) _. func map-triple (func A -> A1), (func B -> B1), (func C -> C1), triple A B C -> triple A1 B1 C1. map-triple F G H (triple X Y Z) (triple X1 Y1 Z1) :- F X X1, G Y Y1, H Z Z1. func sort.split list A -> list A, list A. sort.split [] [] [] :- !. sort.split [X] [X] [] :- !. sort.split [X,Y|TL] [X|L1] [Y|L2] :- sort.split TL L1 L2. % sort.merge can take a relation but keeps only the first solution returned. % There is a cut after the call to `Rel X1 X2`. func sort.merge (pred i:A, i:A), list A, list A -> list A. sort.merge _ [] L L :- !. sort.merge _ L [] L :- !. sort.merge Rel [X1|L1] [X2|L2] [X1|M] :- Rel X1 X2, !, sort.merge Rel L1 [X2|L2] M. sort.merge Rel [X1|L1] [X2|L2] [X2|M] :- sort.merge Rel [X1|L1] L2 M. :index(1) func sort list A, (pred i:A, i:A) -> list A. sort [] _ [] :- !. sort [X] _ [X] :- !. sort L Rel M :- sort.split L L1 L2, sort L1 Rel S1, sort L2 Rel S2, sort.merge Rel S1 S2 M. func bubblesort list A, (pred i:A, i:A) -> list A. bubblesort [] _ [] :- !. bubblesort [X] _ [X] :- !. bubblesort [X,Y|TL] Rel [X|Rest1] :- Rel X Y, !, bubblesort [Y|TL] Rel Rest1. bubblesort [X,Y|TL] Rel [Y|Rest1] :- bubblesort [X|TL] Rel Rest1. % TODO: pred toposort i:(A -> A -> prop), i:list A, o:list A. % pred edge? i:int, i:int. % toposort edge? [1,2,3,4] TopoList func topovisit list (pair A A), A, list A, list A -> list A, list A. topovisit _ X VS PS VS PS :- std.mem PS X, !. topovisit _ X VS _ _ _ :- std.mem VS X, !, halt "cycle detected.". topovisit ES X VS PS VS' [X|PS'] :- toporec ES {std.map {std.filter ES (e\ fst e X)} snd} [X|VS] PS VS' PS'. func toporec list (pair A A), list A, list A, list A -> list A, list A. toporec _ [] VS PS VS PS. toporec ES [X|XS] VS PS VS'' PS'' :- topovisit ES X VS PS VS' PS', toporec ES XS VS' PS' VS'' PS''. func toposort list (pair A A), list A -> list A. toposort ES XS XS'' :- toporec ES XS [] [] _ XS', % @gares: meme!, instead of mem std.filter XS' (std.mem! XS) XS''. namespace gref { func topovisit coq.gref.map coq.gref.set, classname, coq.gref.set, list classname, coq.gref.set -> coq.gref.set, list classname, coq.gref.set. topovisit _ X VS PS PSS VS PS PSS :- coq.gref.set.mem X PSS, !. topovisit _ X VS _ _ _ _ _ :- coq.gref.set.mem X VS, !, halt "cycle detected.". topovisit ES X VS PS PSS VS' [X|PS'] PSS'' :- std.once (coq.gref.map.find X ES M ; coq.gref.set.empty M), toporec ES {coq.gref.set.elements M} {coq.gref.set.add X VS} PS PSS VS' PS' PSS', coq.gref.set.add X PSS' PSS''. :index (_ 1) func toporec coq.gref.map coq.gref.set, list classname, coq.gref.set, list classname, coq.gref.set -> coq.gref.set, list classname, coq.gref.set. toporec _ [] VS PS PSS VS PS PSS. toporec ES [X|XS] VS PS PSS VS'' PS'' PSS'' :- topovisit ES X VS PS PSS VS' PS' PSS', toporec ES XS VS' PS' PSS' VS'' PS'' PSS''. :index (1) func add-to-neighbours coq.gref.set, pair gref gref, coq.gref.map coq.gref.set -> coq.gref.map coq.gref.set. add-to-neighbours VS (pr _ V) A A :- not(coq.gref.set.mem V VS), !. add-to-neighbours _ (pr K V) A A1 :- coq.gref.map.find K A L, !, coq.gref.map.add K {coq.gref.set.add V L} A A1. add-to-neighbours _ (pr K V) A A1 :- coq.gref.map.add K {coq.gref.set.add V {coq.gref.set.empty} } A A1. :index(1) func toposort list (pair gref gref), list gref -> list gref. toposort ES XS XS'' :- !, std.fold XS {coq.gref.set.empty} coq.gref.set.add VS, std.fold ES {coq.gref.map.empty} (add-to-neighbours VS) EM, toporec EM XS {coq.gref.set.empty} [] {coq.gref.set.empty} _ XS'' _ . } func time-do! list prop ->. time-do! []. time-do! [P|PS] :- std.time P Time, !, if (constant P C _) true (C = P), coq.say Time ">>" C, time-do! PS. } namespace compat { % TODO: replace with std.map-filter when coq-elpi > 1.9.2 :index (1) func map-filter list A, (A -> B -> prop) -> list B. map-filter [] _ []. map-filter [X|XS] F [Y|YS] :- F X Y, !, map-filter XS F YS. map-filter [_|XS] F YS :- map-filter XS F YS. } func print-ctx. print-ctx :- declare_constraint print-ctx []. constraint print-ctx mixin-src { rule \ (G ?- print-ctx) | (coq.say "The context is:" G). } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func coq.term-is-gref? term -> gref. coq.term-is-gref? (global GR) GR. coq.term-is-gref? (pglobal GR _) GR. coq.term-is-gref? (app [Hd|_]) GR :- coq.term-is-gref? Hd GR. coq.term-is-gref? (let _ _ T x\x) GR :- coq.term-is-gref? T GR. func coq.prod-tgt->gref term -> gref. coq.prod-tgt->gref T GR :- whd1 T T1, !, coq.prod-tgt->gref T1 GR. coq.prod-tgt->gref (prod N Src Tgt) GR :- !, @pi-decl N Src x\ coq.prod-tgt->gref (Tgt x) GR. coq.prod-tgt->gref End GR :- coq.term->gref End GR. % TODO: move to coq-elpi proper / move to coq.pp in coq-elpi >= 1.9 :index(1) func coq.indt-decl->string indt-decl -> string. coq.indt-decl->string (parameter ID _ Ty D) S :- coq.id->name ID Name, (@pi-decl Name Ty x\ coq.indt-decl->string (D x) S1), S is "Parameter" ^ ID ^ " : " ^ {coq.term->string Ty} ^ "\n" ^ S1. coq.indt-decl->string (inductive _ _ _ _) "NYI". coq.indt-decl->string (record ID Ty KID RD) S :- coq.record-decl->string RD S1, S is ID ^ " : " ^ {coq.term->string Ty} ^ " := " ^ KID ^ " {\n" ^ S1 ^ "}". :index(1) func coq.record-decl->string record-decl -> string. coq.record-decl->string end-record "". coq.record-decl->string (field _ ID Ty D) S :- coq.id->name ID Name, (@pi-decl Name Ty x\ coq.record-decl->string (D x) S1), S is " " ^ ID ^ " : " ^ {coq.term->string Ty} ^ ";\n" ^ S1. :index(1) func coq.ground-indt-decl? indt-decl ->. coq.ground-indt-decl? (parameter ID _ Ty D) :- ground_term Ty, coq.id->name ID Name, (@pi-decl Name Ty x\ coq.ground-indt-decl? (D x)). coq.ground-indt-decl? (inductive _ _ _ _). coq.ground-indt-decl? (record _ Ty _ RD) :- ground_term Ty, coq.ground-record-decl? RD. :index(1) func coq.ground-record-decl? record-decl ->. coq.ground-record-decl? end-record. coq.ground-record-decl? (field _ ID Ty D) :- ground_term Ty, coq.id->name ID Name, (@pi-decl Name Ty x\ coq.ground-record-decl? (D x)). % TODO: remove when coq-elpi > 1.9.3 % func copy-indt-decl indt-decl -> indt-decl. % copy-indt-decl (parameter ID I Ty D) (parameter ID I Ty1 D1) :- % copy Ty Ty1, % @pi-parameter ID Ty1 x\ copy-indt-decl (D x) (D1 x). % copy-indt-decl (inductive ID CO A D) (inductive ID CO A1 D1) :- % copy-arity A A1, % coq.id->name ID N, coq.arity->term A1 T, @pi-decl N T i\ std.map (D i) copy-constructor (D1 i). % % @pi-inductive ID A1 i\ std.map (D i) copy-constructor (D1 i). % requires Coq-Elpi 1.9.x % copy-indt-decl (record ID T IDK F) (record ID T1 IDK F1) :- % copy T T1, % copy-fields F F1. % func copy-fields record-decl -> record-decl. % copy-fields end-record end-record. % copy-fields (field Att ID T F) (field Att ID T1 F1) :- % copy T T1, % @pi-parameter ID T1 x\ copy-fields (F x) (F1 x). % func copy-constructor indc-decl -> indc-decl. % copy-constructor (constructor ID A) (constructor ID A1) :- copy-arity A A1. % TODO: move to coq-elpi proper func coq.gref.list->set list gref -> coq.gref.set. coq.gref.list->set L S :- std.fold L {coq.gref.set.empty} coq.gref.set.add S. % [coq.abstract-indt-decl Section I AbsI] abstracts I over the Section variables % which becomes parameter nodes of the indt-decl type :index(1) func coq.abstract-indt-decl list constant, indt-decl -> indt-decl. coq.abstract-indt-decl [] X X1 :- copy-indt-decl X X1. coq.abstract-indt-decl [C|CS] X (parameter ID explicit Ty1 X1) :- coq.gref->id (const C) ID, coq.env.typeof (const C) Ty, copy Ty Ty1, @pi-parameter ID Ty x\ (copy (global (const C)) x :- !) => coq.abstract-indt-decl CS X (X1 x). % [coq.abstract-const-decl Section I AbsI] abstracts I over the Section variables % which becomes fun nodes :index (1) func coq.abstract-const-decl list constant, pair term term -> pair term term. coq.abstract-const-decl [] (pr X Y) (pr X1 Y1) :- copy X X1, copy Y Y1. coq.abstract-const-decl [C|CS] X (pr (fun Name Ty1 X1) (prod Name Ty1 X2)) :- coq.gref->id (const C) ID, coq.id->name ID Name, coq.env.typeof (const C) Ty, copy Ty Ty1, @pi-parameter ID Ty x\ (copy (global (const C)) x :- !) => coq.abstract-const-decl CS X (pr (X1 x) (X2 x)). % [coq.copy-clauses-for-unfold CS CL] generates clauses for the copy predicate % to unfold all constants in CS :index(1) func coq.copy-clauses-for-unfold list constant -> list prop. coq.copy-clauses-for-unfold [] []. coq.copy-clauses-for-unfold [C|CS] [ClauseApp,Clause|L] :- coq.env.const C (some B) _, ClauseApp = (pi B1 Args Args1 B2 Args2 R\ copy (app[global (const C)|Args]) R :- !, copy B B1, std.map Args copy Args1, hd-beta B1 Args1 B2 Args2, unwind B2 Args2 R), Clause = (pi B1\ copy (global (const C)) B1 :- !, copy B B1), coq.copy-clauses-for-unfold CS L. % like fold-map, needed for coq-elpi < 1.9 func coq.fold-map term, A -> term, A. coq.fold-map X A Y A :- name X, !, X = Y, !. % avoid loading "coq.fold-map x A x A" at binders coq.fold-map (global _ as C) A C A :- !. coq.fold-map (sort _ as C) A C A :- !. coq.fold-map (fun N T F) A (fun N T1 F1) A2 :- !, coq.fold-map T A T1 A1, pi x\ coq.fold-map (F x) A1 (F1 x) A2. coq.fold-map (let N T B F) A (let N T1 B1 F1) A3 :- !, coq.fold-map T A T1 A1, coq.fold-map B A1 B1 A2, pi x\ coq.fold-map (F x) A2 (F1 x) A3. coq.fold-map (prod N T F) A (prod N T1 F1) A2 :- !, coq.fold-map T A T1 A1, (pi x\ coq.fold-map (F x) A1 (F1 x) A2). coq.fold-map (app L) A (app L1) A1 :- !, std.fold-map L A coq.fold-map L1 A1. coq.fold-map (fix N Rno Ty F) A (fix N Rno Ty1 F1) A2 :- !, coq.fold-map Ty A Ty1 A1, pi x\ coq.fold-map (F x) A1 (F1 x) A2. coq.fold-map (match T Rty B) A (match T1 Rty1 B1) A3 :- !, coq.fold-map T A T1 A1, coq.fold-map Rty A1 Rty1 A2, std.fold-map B A2 coq.fold-map B1 A3. coq.fold-map (primitive _ as C) A C A :- !. coq.fold-map (uvar M L as X) A W A1 :- var X, !, std.fold-map L A coq.fold-map L1 A1, coq.mk-app-uvar M L1 W. % when used in CHR rules coq.fold-map (uvar X L) A (uvar X L1) A1 :- std.fold-map L A coq.fold-map L1 A1. func cs-pattern->term cs-pattern -> term. cs-pattern->term (cs-gref GR) T :- coq.env.global GR T. cs-pattern->term (cs-sort prop) (sort prop) :- !. cs-pattern->term (cs-sort sprop) (sort sprop) :- !. cs-pattern->term (cs-sort _) T :- coq.elaborate-skeleton {{ Type }} _ T ok. cs-pattern->term cs-prod T :- coq.elaborate-skeleton (prod `x` Ty_ x\ Bo_ x) _ T ok. func term->cs-pattern term -> cs-pattern. term->cs-pattern (prod _ _ _) cs-prod :- !. term->cs-pattern (sort U) (cs-sort U) :- !. term->cs-pattern T (cs-gref GR) :- coq.term->gref T GR, !. term->cs-pattern T _ :- coq.error T "HB database: is not a valid canonical key". % --------------------------------------------------------------------- % kit for closing a term by abstracting evars with lambdas % we use constraints to attach to holes a number % and replace them by a special node, to later be bound % via a lambda namespace abstract-holes { % we add a new constructor to terms to represent terms to be abstracted type abs int -> term. % bind back abstracted subterms func bind int, int, term -> term. bind I M T T1 :- M > I, !, T1 = {{ fun x => lp:(B x) }}, N is I + 1, pi x\ % we allocate the fresh symbol for (abs M) (copy (abs N) x :- !) => % we schedule the replacement (abs M) -> x bind N M T (B x). bind M M T T1 :- copy T T1. % we perform all the replacements % for a term with M holes, returns a term with M variables to fill these holes % the clause see is only generated for a term if it hasn't been seen before % the term might need to be typechecked first or main generates extra holes for the % type of the parameters func main term -> term. main T1 T3 :- std.do! [ % we put (abs N) in place of each occurrence of the same hole (pi T Ty N N' M \ fold-map T N (abs M) M :- var T, not (seen? T _), !, coq.typecheck T Ty ok, fold-map Ty N _ N', M is N' + 1, seen! T M) => (pi T N M \ fold-map T N (abs M) N :- var T, seen? T M, !) => fold-map T1 0 T2 M, % we abstract M holes (M abs nodes) bind 0 M T2 T3, % cleanup constraint store purge-seen!, ]. % all constraints are also on _ so that they share % a variable with the constraint to purge the store % we query if the hole was seen before, and if so % we fetch its number func seen? term -> int. seen? X Y :- declare_constraint (seen? X Y) [X,_]. % we declare it is now seen and label it with a number func seen! term, int ->. seen! X Y :- declare_constraint (seen! X Y) [X,_]. % to empty the store func purge-seen!. purge-seen! :- declare_constraint purge-seen! [_]. constraint seen? seen! purge-seen! { % a succesful query, give the label back via M rule (seen! X N) \ (seen? X M) <=> (M = N). % an unsuccesful query rule \ (seen? X _) <=> false. rule purge-seen! \ (seen! _ _). rule \ purge-seen!. } }math-comp-hierarchy-builder-4d8a939/HB/common/synthesis.elpi000066400000000000000000000337161521677141400240550ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file implements a simple form of "type inference" for arguments which % are mixins and can be inferred looking at the \lambda Prolog context, in % particular [mixins-src] context entries (the one of Coq looks at CS databases % and such, which cannot be easily manipulated on the fly). % % If provides function to infer this kind of arguments and to declare a context % made of mixins to be used for such inference. The idea is that one has % a bunch of mixins at hand and does want to pass them down to other terms, % without explictly saying exactly where they should be used. namespace synthesis { % [infer-all-these-mixin-args Ps T ML F X] fills in all the arguments of F % which are misxins in ML, abstracts the others func infer-all-these-mixin-args list term, term, list mixinname, term -> term. infer-all-these-mixin-args Ps T ML F SFX :- std.do! [ std.assert-ok! (coq.typecheck F Ty) "try-infer-these-mixin-args: F illtyped", coq.mk-eta (-1) Ty F EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-these-mixin-args FT T ML SFX, ]. % [infer-all-gref->deps Ps T GR X] fills in all the arguments of GR % which are misxins in gref->deps GR, other arguments are abstracted func infer-all-gref->deps list term, term, gref -> term. infer-all-gref->deps Ps T GR X :- std.do! [ std.assert! (gref->deps GR MLwP) "BUG: gref->deps should never fail", list-w-params_list MLwP ML, coq.env.typeof GR Ty, coq.mk-eta (-1) Ty (global GR) EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-these-mixin-args FT T ML Xraw, infer-holes-depending-on-params T Xraw X, ]. % [infer-holes-depending-on-params TheType T NewT] func infer-holes-depending-on-params term, term -> term. infer-holes-depending-on-params T (app [global GR|Args]) (app [global GR|Args1]) :- !, std.map Args (infer-holes-depending-on-pack T) Args1. infer-holes-depending-on-params _ X X. func class-of-phant term -> gref, gref, gref. class-of-phant (prod N T F) X Y Z :- @pi-decl N T x\ class-of-phant (F x) X Y Z. class-of-phant (global GR) Y Z X :- class-def (class X GR _), !, get-constructor X Y, get-constructor GR Z. class-of-phant (app[global GR|_]) Y Z X :- class-def (class X GR _), !, get-constructor X Y, get-constructor GR Z. func infer-holes-depending-on-pack term, term -> term. infer-holes-depending-on-pack T (app [global GR | Args]) S :- ((coq.gref->id GR GRS, rex.match "phant.*" GRS /*TODO: phant-clone? GR N*/); pack? GR _), coq.env.typeof GR Ty, class-of-phant Ty KC SC C, factory->nparams C N, std.take N Args Params, !, std.do! [ infer-all-args-let Params T KC ClassInstance ok, std.rev [ClassInstance,T|{std.rev Params}] NewArgs, S = app[global SC| NewArgs ] ]. infer-holes-depending-on-pack _ X X. % [infer-all-args-let Ps T GR X Diagnostic] fills in all the Args in % app[global GR, Ps, T | Args] % and generates a term % let `a1` ty1 t1 a1\ .... app[global GR, p1, .. pn, T, a1, .. , an] % if Diagnostic is ok, else X is unassigned func infer-all-args-let list term, term, gref -> term, diagnostic. infer-all-args-let Ps T GR X Diag :- std.do! [ coq.env.typeof GR Ty, coq.mk-eta (-1) Ty (global GR) EtaF, coq.subst-fun {std.append Ps [T]} EtaF FT, private.instantiate-all-args-let FT T X Diag, ]. % [assert!-infer-mixin TheType M Out] infers one mixin M on TheType and % aborts with an error message if the mixin cannot be inferred func assert!-infer-mixin term, mixinname -> term. assert!-infer-mixin T M B :- if (private.mixin-for T M B) true (coq.error "HB: cannot inhabit mixin" {nice-gref->string M} "on"{coq.term->string T}). % Given TheType it looks all canonical structure instances on it and makes % all their mixins available for inference :index (_ 1) func local-canonical-mixins-of.aux term, list structure -> list prop. local-canonical-mixins-of.aux _ [] []. local-canonical-mixins-of.aux T [S|Ss] MSL'' :- std.do! [ private.structure-instance->mixin-srcs T S MSL, MSL => local-canonical-mixins-of.aux T Ss MSL', std.append MSL MSL' MSL'', ]. func local-canonical-mixins-of term -> list prop. local-canonical-mixins-of T MSL :- std.do! [ get-canonical-structures T CS, std.map CS (s\c\ sigma w\ class-def (class c s w)) Cl, toposort-classes Cl ClSorted, std.map ClSorted (c\s\ sigma w\ class-def (class c s w)) CSSorted, local-canonical-mixins-of.aux T CSSorted MSL, ]. % Given TheType and a factory instance (on it), makes all the mixins provided by % the factory available for inference. func under-mixin-src-from-factory.do! term, term, list prop. under-mixin-src-from-factory.do! TheType TheFactory LP :- private.factory-instance->new-mixins [] TheFactory ML, std.map ML (m\c\ c = mixin-src TheType m TheFactory) MLClauses, MLClauses => std.do! LP. % Given TheType and a factory instance (on it), builds all the *new* mixins % provided by the factory available for and passes them to the given % continuation func under-new-mixin-src-from-factory.do! term, term, (list mixinname -> prop). under-new-mixin-src-from-factory.do! TheType TheFactory LP :- findall-mixin-src TheType OldMixins, private.factory-instance->new-mixins OldMixins TheFactory NewML, std.map NewML (m\c\ c = mixin-src TheType m TheFactory) NewMLClauses, NewMLClauses => std.once (LP NewML). % [under-mixins.then MLwP Pred F] states that F has shape % fun p_1 .. p_k T, % (m_0 : M_0 ..p.. T) .. (m_n : M_n ..p.. T m_i0 .. m_ik) => % Body m_0 .. m_n % where MLwP contains M_0, .., M_n (under p_1 .. p_k) % and Body is such that [..,mixin-src T M_i m_i,..] => Pred Body % and ..p.. is a list of terms built using p_1 .. p_k and T func under-mixins.then list (w-args mixinname), (pred i:name, i:term, i:(term -> A), o:A), (func A -> ) -> A. under-mixins.then [] _ Pred Body :- !, Pred Body. under-mixins.then [triple M Args T|ML] MkFun Pred Out :- std.do! [ infer-all-gref->deps Args T M MTy, (@pi-decl `m` MTy m\ mixin-src T M m => under-mixins.then ML MkFun Pred (Body m)), MkFun `m` MTy Body Out, ]. % [mixins-w-params.fun MLwP Pred F] states that F has shape % fun p_1 .. p_k T, % (m_0 : M_0 ..p.. T) .. (m_n : M_n ..p.. T m_i0 .. m_ik) => % Body m_0 .. m_n % where MLwP contains M_0, .., M_n (under p_1 .. p_k) % and Body is such that [..,mixin-src T M_i m_i,..] => Pred Body % and ..p.. is a list of terms built using p_1 .. p_k and T func mixins-w-params.fun mixins, (func list term, term -> term) -> term. mixins-w-params.fun L P Out :- !, w-params.then L mk-fun mk-fun (p\ t\ ml\ under-mixins.then ml mk-fun (P p t)) Out. % [mixins-w-params.length LwP N] states N is Nmixins+Nparams func mixins-w-params.length mixins -> int. mixins-w-params.length MLwP N :- w-params.nparams MLwP Nparams, std.length {list-w-params_list MLwP} Nmixins, N is Nparams + Nmixins. func infer-coercion-tgt mixins -> class. infer-coercion-tgt (w-params.cons ID Ty F) CoeClass :- @pi-parameter ID Ty x\ infer-coercion-tgt (F x) CoeClass. infer-coercion-tgt (w-params.nil _ {{ Type }} _) sortclass :- !. infer-coercion-tgt (w-params.nil _ {{ forall x, _ }} _) funclass :- !. % do not use {{ _ -> _ }} since Funclass can be a dependent function! infer-coercion-tgt (w-params.nil _ T _) (grefclass GR) :- coq.term->gref T GR. :index (_ _ 2) func w-args.check-key list term, term, list (w-args A) -> prop. w-args.check-key _PS _T [] true :- !. w-args.check-key PS T [triple _ _ T|LwA] P :- !, w-args.check-key PS T LwA P. w-args.check-key _PS _T _LwA false :- !, coq.error "HB: all mixins must have the same key". func list-w-params.check-key list-w-params A ->. list-w-params.check-key MLwP :- !, w-params.then MLwP ignore ignore w-args.check-key _. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % [mixin-for T M MI] synthesizes an instance of mixin M on type T using % the databases [mixin-src] and [from] func mixin-for term, mixinname -> term. mixin-for T M MICompressed :- mixin-src T M Tm, !, %if-verbose (coq.say {header} "Trying to infer mixin for" M), std.assert-ok! (coq.typecheck Tm Ty) "mixin-for: Tm illtyped", %%%%% mterm %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% factory? Ty (triple Factory Params _), if (M = Factory) (MI = Tm) ( private.builder->term Params T Factory M B, coq.subst-fun [Tm] B MI ), %if-verbose (coq.say {header} "Trying to compress mixin for" {coq.term->string MI}), compress-coercion-paths MI MICompressed. func drop int, list A -> list A. drop 0 L L :- !. drop N [_|XS] L :- !, N1 is N - 1, drop N1 XS L. func compress-copy -> term, term. compress-copy (app [global (const C) | L]) R :- sub-class C2 C3 C NparamsC, drop NparamsC L [app [global (const C') | L']], sub-class C1 C2 C' NparamsC', drop NparamsC' L' L'', sub-class C1 C3 C'' NparamsC'', std.append {coq.mk-n-holes NparamsC''} L'' HL'', CHL'' = app [global (const C'') | HL''], coq.typecheck CHL'' _ ok, !, compress-copy CHL'' R. compress-copy (app L) (app L1) :- !, std.map L compress-copy L1. compress-copy X X. func compress-coercion-paths term -> term. compress-coercion-paths MI MICompressed :- if (get-option "compress_coercions" tt) (compress-copy MI MICompressed) (MI = MICompressed). func mixin-for_mixin-builder prop -> term. mixin-for_mixin-builder (mixin-for _ _ B) B. % [builder->term Params TheType Src Tgt MF] finds a builder from Src to Tgt % and fills in all the mixins required by the builder using mixin-src, obtaining % a function (MF = Builder Params TheType InferredStuff : Src -> Tgt) func builder->term list term, term, factoryname, mixinname -> term. builder->term Ps T Src Tgt B :- !, std.do! [ from Src Tgt FGR, F = global FGR, gref->deps Src MLwP, list-w-params_list MLwP ML, infer-all-these-mixin-args Ps T ML F B, ]. % [instantiate-all-these-mixin-args T F M_i TFX] where mixin-for T M_i X_i states that % if F ~ fun xs (m_0 : M_0 T) .. (m_n : M_n T ..) ys % => F xs m_0 .. m_{i-1} m_i m_{i+1} .. m_n ys % then TFX := fun xs m_0 .. m_{i-1} m_{i+1} .. m_n ys % => F xs m_0 .. m_{i-1} X_i m_{i+1} .. m_n ys % thus instanciating an abstraction on mixin M_i with X_i func instantiate-all-these-mixin-args term, term, list mixinname -> term. instantiate-all-these-mixin-args (fun _ Tm F) T ML R :- coq.safe-dest-app Tm (global TmGR) _, factory-alias->gref TmGR M ok, std.mem! ML M, !, if (mixin-for T M X) true (coq.error "HB: Unable to find mixin" {nice-gref->string M} "on subject" {coq.term->string T}), !, instantiate-all-these-mixin-args (F X) T ML R. instantiate-all-these-mixin-args (fun N Ty F) T ML (fun N Ty FX) :- !, @pi-decl N Ty m\ instantiate-all-these-mixin-args (F m) T ML (FX m). instantiate-all-these-mixin-args F _ _ F. func instantiate-all-args-let term, term -> term, diagnostic. instantiate-all-args-let (fun N Tm F) T (let N Tm X R) Diag :- !, std.do! [ coq.safe-dest-app Tm (global TmGR) _, factory-alias->gref TmGR M ok, if (mixin-for T M X) (@pi-def N Tm X m\ instantiate-all-args-let (F m) T (R m) Diag) (Diag = error Msg, Msg is "cannot synthesize mixin " ^ {nice-gref->string M} ^ " for " ^ {coq.term->string T}), ]. instantiate-all-args-let F _ F ok. % [structure-instance->mixin-srcs TheType Structure] finds a CS instance for % Structure on TheType (if any) and builds mixin-src clauses for all the mixins % which can be candidates from that class instance. It finds instances which are % concrete, that is not by projecting a rich type (a variable) to its class. pred structure-instance->mixin-srcs i:term, i:structure, o:list prop. structure-instance->mixin-srcs T S MSLC :- std.do! [ structure-key SortProj _ S, class-def (class (indt Class) S CMLwP), structure-nparams S NParams, coq.mk-n-holes NParams Holes, std.append Holes [ST] HolesST, coq.mk-app (global (const SortProj)) HolesST SortHolesST, % find an instance in ST coq.unify-eq T SortHolesST ok, % we look for an instance which is concrete, we take the parts get-constructor S KS, coq.mk-app (global KS) {std.append Holes [T, CT]} KSHolesC, coq.unify-eq ST KSHolesC ok, % if the class instance is concrete, we take the parts get-constructor (indt Class) KC, std.length {list-w-params_list CMLwP} CMixinsN, coq.mk-n-holes CMixinsN MIL, coq.mk-app (global KC) {std.append Holes [T | MIL]} CBody, coq.unify-eq CT CBody ok, % we finally generare micin-src clauses for all mixins std.map MIL (structure-instance->mixin-srcs.aux T) MSLL, std.flatten MSLL MSLC, ]. % this catch all sucks a bit, but is very relevant. Some instance, like % unification hints (canonical coercions) which require a type which is too rich % fail the second unif problem structure-instance->mixin-srcs _ _ []. structure-instance->mixin-srcs.aux2 Params T Class (some P) M :- coq.mk-app (global (const P)) {std.append Params [T,Class]} M. func structure-instance->mixin-srcs.aux term, term -> list prop. structure-instance->mixin-srcs.aux T F CL :- factory-instance->new-mixins [] F ML, std.map-filter ML (m\c\ not (mixin-src T m _), c = mixin-src T m F) CL. % [factory-instance->new-mixins OldMixins FI MSL] find all the mixins % which can be generated by the factory instance FI which are not part of % OldMixins (that is, the contribution of FI to the current context) func factory-instance->new-mixins list mixinname, term -> list mixinname. factory-instance->new-mixins OldMixins X NewML :- std.assert-ok! (coq.typecheck X XTy) "mixin-src: X illtyped", if (not (coq.safe-dest-app XTy (global _) _)) (coq.error "Term:\n" {coq.term->string X} "\nhas type:\n" {coq.term->string XTy} "\nwhich is not a record") true, coq.term->gref XTy Src, factory-provides Src MLwP, list-w-params_list MLwP ML, std.filter ML (m\ not(std.mem! OldMixins m)) NewML. }} math-comp-hierarchy-builder-4d8a939/HB/common/utils-synterp.elpi000066400000000000000000000046601521677141400246620ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % runs P in a context where Coq #[attributes] are parsed func with-attributes (func). with-attributes P :- attributes A, coq.parse-attributes A [ att "verbose" bool, att "mathcomp" bool, att "mathcomp.axiom" string, att "short.type" string, att "short.pack" string, att "key" string, att "arg_sort" bool, att "log" bool, att "log.raw" bool, att "compress_coercions" bool, att "export" bool, att "skip" string, att "local" bool, att "fail" bool, att "doc" string, att "primitive" bool, att "non_forgetful_inheritance" bool, att "hnf" bool, ] Opts, !, Opts => (save-docstring, P). func if-verbose (func) -> . if-verbose P :- get-option "verbose" tt, !, P. if-verbose _. % header of if-verbose messages func header -> string. header Msg :- Msg is "[" ^ {std.any->string {gettimeofday}} ^ "] HB: ". % approximation, it should be logical path, not the file name func coq.env.current-library -> string. coq.env.current-library L :- loc.fields {get-option "elpi.loc"} L _ _ _ _, !. coq.env.current-library "dummy.v". % this is only declared in hb.db, this declaration is only to avoid a warning pred docstring o:loc, o:string. func save-docstring. save-docstring :- if (get-option "elpi.loc" Loc, get-option "elpi.phase" "interp", get-option "doc" Txt) (coq.elpi.accumulate _ "hb.db" (clause _ _ (docstring Loc Txt))) true. func compute-filter option string -> list string. compute-filter none []. compute-filter (some S) MFilter :- % S is a component of the current modpath coq.env.current-path P, rex_split "\\." S L, compute-filter.aux P L MFilter, !. compute-filter (some S) MFilter :- coq.locate-module S M, coq.modpath->path M MFilter. func compute-filter.aux list string, list string -> list string. compute-filter.aux [S|_] [S] [S] :- !. compute-filter.aux [S|XS] [S|SS] [S|YS] :- !, compute-filter.aux XS SS YS. compute-filter.aux [X|XS] L [X|YS] :- compute-filter.aux XS L YS. func list-uniq list A -> list A. pred list-uniq.seen i:A. list-uniq [] []. list-uniq [X|XS] YS :- list-uniq.seen X, !, list-uniq XS YS. list-uniq [X|XS] [X|YS] :- list-uniq.seen X => list-uniq XS YS. func record-decl->id indt-decl -> id. record-decl->id (parameter _ _ _ D) N :- pi p\ record-decl->id (D p) N. record-decl->id (record N _ _ _) N. math-comp-hierarchy-builder-4d8a939/HB/common/utils.elpi000066400000000000000000000340761521677141400231640ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ % This file contains some HB specific utilities accumulate HB/common/utils-synterp. shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. func if-arg-sort (func) ->. if-arg-sort P :- get-option "arg_sort" tt, !, P. if-arg-sort _. func if-MC-compat (func option gref ->) ->. if-MC-compat P :- get-option "mathcomp" tt, !, P none. if-MC-compat P :- get-option "mathcomp.axiom" S, !, std.assert! (coq.locate S GR) "The name passed to the mathcomp.axiom attribute does not exist", P (some GR). if-MC-compat _. func with-locality (func) ->. with-locality P :- if (get-option "local" tt) (A = @local!) (A = @global!), A => P. func acc-clause scope, prop. acc-clause Scope C :- coq.elpi.accumulate Scope "hb.db" (clause _ _ C). /* Uncomment and remove HB/common/compat_acc_clauses_*.elpi once requiring coq-elpi >= 1.18.0, which implies Coq >= 8.17 pred acc-clauses i:scope, i:list prop. acc-clauses Scope CL :- coq.elpi.accumulate-clauses Scope "hb.db" {std.map CL (c\r\ r = clause _ _ c)}. */ % TODO: Should this only be used for gref that are factories? (and check in the first/second branch so?) % Should we make this an HO predicate, eg "located->gref S L is-factory? GR" % TODO: rename since this is HB specific and is expected to return a factory :index (_ 2) func located->gref string, list located -> gref. located->gref _ [loc-gref GR|_] GR. located->gref _ [loc-abbreviation Abbrev|_] GR :- phant-abbrev GR _ Abbrev, !. located->gref S [loc-abbreviation _|_] _ :- coq.error S "is an abbreviation out of the control of HB". located->gref S [loc-modpath _|_] _ :- coq.error S "should be a factory, but is a module". located->gref S [loc-modtypath _|_] _ :- coq.error S "should be a factory, but is a module type". located->gref S [] _ :- coq.error "Could not locate name" S. % TODO: generalize/rename when we support parameters func argument->gref argument -> gref. argument->gref (str S) GR :- !, located->gref S {coq.locate-all S} GR. argument->gref X _ :- coq.error "Argument" X "is expected to be a string". func argument->term argument -> term. argument->term (str S) (global GR) :- !, argument->gref (str S) GR. argument->term (trm T) T1 :- !, std.assert-ok! (coq.elaborate-skeleton T _ T1) "not well typed term". argument->term X _ :- coq.error "Argument" X " is expected to be a term or a string". func argument->ty argument -> term. argument->ty (str S) T1 :- !, argument->gref (str S) GR, std.assert-ok! (coq.elaborate-ty-skeleton (global GR) _ T1) "global reference is not a type". argument->ty (trm T) T1 :- !, std.assert-ok! (coq.elaborate-ty-skeleton T _ T1) "not well typed type". argument->ty X _ :- coq.error "Argument" X " is expected to be a type or a string". func builder->string builder -> string. builder->string (builder _ _ _ B) S :- coq.term->string (global B) S. func nice-gref->string gref -> string. nice-gref->string X Mod :- coq.gref->path X Path, std.rev Path [Mod1,Mod2|_], !, Mod is Mod2 ^ "_" ^ Mod1. nice-gref->string X S :- coq.term->string (global X) S. func gref->modname gref, int, string -> string. gref->modname GR NComp Sep ModName :- coq.gref->path GR Path, std.rev Path Mods, std.length Path Len, if (Len >= NComp) true (coq.error "Not enough enclosing modules for" {coq.gref->string GR}), std.take NComp Mods L, std.string.concat Sep {std.rev L} ModName. func gref->modname-label gref, int, string -> string. gref->modname-label GR NComp Sep ModName :- coq.gref->path GR Path, std.rev Path PathRev, std.length PathRev Len, if (Len >= NComp) (N = NComp) (N = Len), std.take N PathRev L, std.string.concat Sep {std.rev [{coq.gref->id GR}|L]} ModName. func cs-pattern->name cs-pattern -> string. cs-pattern->name cs-prod "prod". cs-pattern->name (cs-sort _) "sort". cs-pattern->name cs-default "default". cs-pattern->name (cs-gref GR) Name :- gref->modname-label GR 1 "_" Name. func string->modpath string -> modpath. string->modpath S MP :- std.filter {coq.locate-all S} (l\l = loc-modpath _) L, L = [loc-modpath MP]. func gref->modname_short1 modpath, string, list string -> string. gref->modname_short1 _ S [] S :- !. gref->modname_short1 MP "" [X|L] L' :- !, gref->modname_short1 MP X L L'. gref->modname_short1 MP S _ S :- string->modpath S MP, !. gref->modname_short1 MP S [X|L] S' :- gref->modname_short1 MP {std.string.concat "." [X,S]} L S'. % Print shortest qualified identifier of the module containing a gref % Sep is used as separator func gref->modname_short gref, string -> string. gref->modname_short GR Sep IDS :- coq.gref->path GR Path, string->modpath {std.string.concat "." Path} MP, gref->modname_short1 MP "" {std.rev Path} ID, rex.replace "[.]" Sep ID IDS. func avoid-name-collision string -> string. avoid-name-collision S S1 :- coq.locate-all S L, if (std.mem L (loc-gref GR), coq.gref->path GR P, coq.env.current-path P) (S1 is S ^ "__" ^ {std.any->string {new_int}}) (S1 is S). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % function to predicate generic constructions % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% func mk-nil -> list A. mk-nil []. func mk0 A -> A. mk0 F R :- constant R F []. func mk1 (A -> B), A -> B. mk1 F X1 R :- constant R F [X1]. func mk2 (A -> A -> C), A, A -> C. mk2 F X1 X2 R :- constant R F [X1, X2]. func mk3 (A -> A -> A -> D), A, A, A -> D. mk3 F X1 X2 X3 R :- constant R F [X1, X2, X3]. func mk4 (A -> A -> A -> A -> E), A, A, A, A -> E. mk4 F X1 X2 X3 X4 R :- constant R F [X1, X2, X3,X4]. func mk-fun name, term, (term -> term) -> term. mk-fun N Ty Body (fun N Ty Body). % generic argument to pass to w-params func ignore name, term, (term -> A) -> A. ignore _ _ F X :- (pi x y\ F x = F y), X = F (sort prop). % combining body and type func mk-fun-prod name, term -> (term -> pair term term), pair term term. mk-fun-prod N Ty (x\ pr (Body x) (Type x)) (pr (fun N Ty Body) (prod N Ty Type)). func mk-parameter implicit_kind, name, term, (term -> indt-decl) -> indt-decl. mk-parameter IK Name X F (Decl : indt-decl) :- !, Decl = parameter {coq.name->id Name} IK X F. func mk-parameter implicit_kind, name, term, (term -> arity) -> arity. mk-parameter IK Name X F (Decl : arity) :- !, Decl = parameter {coq.name->id Name} IK X F. func params->holes list-w-params A -> list term. params->holes (w-params.nil _ _ _) []. params->holes (w-params.cons _ _ F) [_|PS] :- pi x\ params->holes (F x) PS. func fresh-type -> term. fresh-type Ty :- Ty = {{Type}}, std.assert-ok! (coq.typecheck-ty Ty _) "impossible". %%%%%%%%%%%%%%%%%%%%%% % w-params interface % %%%%%%%%%%%%%%%%%%%%%% :index (1) func apply-w-params w-params A, list term, term -> A. apply-w-params (w-params.cons _ _ PL) [P|PS] T R :- !, apply-w-params (PL P) PS T R. apply-w-params (w-params.nil _ _ L) [] T R :- !, R = L T. apply-w-params _ _ _ _ :- coq.error "apply-w-params". :index (1) func w-params.nparams w-params A -> int. w-params.nparams (w-params.cons _ _ F) N :- pi x\ w-params.nparams (F x) M, N is M + 1. w-params.nparams (w-params.nil _ _ _) 0. % [w-params.fold AwP Cons Nil Out] states that Out has shape % Cons `x_1` T_1 p_1 \ .. \ Nil [p_1 .. p_n] `T` Ty F % where AwP = w-params.cons `x_1` T_1 p_1 \ ... \ w-params.nil `T` Ty F :index (1) func w-params.fold w-params A, (func name, term, (term -> B) -> B), (func list term, name, term, (term -> A) -> B) -> B. w-params.fold L Cons Nil Out :- w-params.fold.params L Cons Nil [] Out. :index (1) func w-params.fold.params w-params A, (func name, term, (term -> B) -> B), (func list term, name, term, (term -> A) -> B), list term % accumulator -> B. w-params.fold.params (w-params.cons ID PTy F) Cons Nil RevPs Out :- !, std.do! [ coq.id->name ID N, (@pi-decl N PTy p\ w-params.fold.params (F p) Cons Nil [p|RevPs] (Body p)), Cons N PTy Body Out]. w-params.fold.params (w-params.nil ID TTy F) _ Nil RevParams Out :- !, std.do! [ coq.id->name ID N, std.rev RevParams Params, Nil Params N TTy F Out, ]. % [w-params.then AwP Cons Nil Out] states that Out has shape % Cons `x_1` T_1 p_1 \ .. \ Nil [p_1 .. p_n] `T` Ty t \ Body % where Pred [p_1 .. p_n] T Body % and AwP = w-params.cons `x_1` T_1 p_1 \ ... \ w-params.nil `T` Ty F :index (1) func w-params.then w-params A, (func name, term, (term -> C) -> C), (func name, term, (term -> B) -> C), (func list term, term, A -> B) -> C. w-params.then L Cons Nil Pred Out :- w-params.fold L Cons (ps\ n\ ty\ f\ out\ sigma Body\ (@pi-decl n ty t\ Pred ps t (f t) (Body t)), Nil n ty Body out) Out. func w-params.map w-params A, (func list term, term, A -> B) -> w-params B. w-params.map AL F BL :- w-params.then AL mk-w-params.cons-name mk-w-params.nil-name F BL. % TODO: make combinators pass id func mk-w-params.cons-name name, term, (term -> w-params A) -> w-params A. mk-w-params.cons-name N T F (w-params.cons ID T F):- coq.name->id N ID. func mk-w-params.nil-name name, term, (term -> A) -> w-params A. mk-w-params.nil-name N T F (w-params.nil ID T F):- coq.name->id N ID. % on the fly abstraction func bind-nil id, term, term, A -> w-params A. bind-nil N T X V (w-params.nil N T A) :- V = A X. func bind-cons id, term, term, w-params A -> w-params A. bind-cons N T X V (w-params.cons N T A) :- V = A X. % Specific to list-w-params func list-w-params_list list-w-params A -> list A. list-w-params_list AwP R :- w-params.then AwP ignore ignore (p\ t\ x\ std.map x triple_1) R. :index (1) func list-w-params.append list-w-params A, list-w-params A -> list-w-params A. list-w-params.append (w-params.nil N T ML1) (w-params.nil N T ML2) (w-params.nil N T ML) :- pi x\ std.append (ML1 x) (ML2 x) (ML x). list-w-params.append (w-params.cons N Ty ML1) (w-params.cons N Ty ML2) (w-params.cons N Ty ML) :- pi x\ list-w-params.append (ML1 x) (ML2 x) (ML x). :index (1) func list-w-params.rcons list-w-params A, (func list term, term -> w-args A) -> list-w-params A. list-w-params.rcons LwP F R :- list-w-params.rcons.aux LwP F [] R. :index (1) func list-w-params.rcons.aux list-w-params A, (func list term, term -> w-args A), list term -> list-w-params A. list-w-params.rcons.aux (w-params.nil N T ML1) F Acc (w-params.nil N T ML2) :- pi x\ sigma Last\ F {std.rev Acc} x Last, std.append (ML1 x) [Last] (ML2 x). list-w-params.rcons.aux (w-params.cons N Ty ML1) F Acc (w-params.cons N Ty ML2) :- pi x\ list-w-params.rcons.aux (ML1 x) F [x|Acc] (ML2 x). func list-w-params.flatten-map list-w-params A, (func A -> list-w-params B) -> list-w-params B. list-w-params.flatten-map (w-params.cons N T L) F (w-params.cons N T L1) :- @pi-parameter N T p\ list-w-params.flatten-map (L p) F (L1 p). list-w-params.flatten-map (w-params.nil N TTy L) F (w-params.nil N TTy L1) :- @pi-parameter N TTy t\ list-w-params.flatten-map.aux (L t) F (L1 t). func list-w-params.flatten-map.aux list (w-args A), (func A -> list-w-params B) -> list (w-args B). list-w-params.flatten-map.aux [] _ []. list-w-params.flatten-map.aux [triple M Ps T|L] F Res1 :- F M MwP, apply-w-params MwP Ps T ML, list-w-params.flatten-map.aux L F Res, std.append ML Res Res1. % [build-list-w-params TheParams TheType Factories ListWParams] % Params is a list of pairs (section variable, its type). % ListWParams has as many w-params.cons as TheParams and the terms % in Factories are abstracted wrt the first component of TheParams. func build-list-w-params list (triple id term term), term, list (w-args A) -> list-w-params A. build-list-w-params [triple ID P Pty|PS] TheType Factories (w-params.cons ID Pty1 R) :- std.do! [ copy Pty Pty1, (@pi-parameter ID Pty1 p\ (copy P p :- !) => build-list-w-params PS TheType Factories (R p)), ]. build-list-w-params [] TheType Factories (w-params.nil Name TT1 R) :- std.do! [ std.assert-ok! (coq.typecheck TheType TT) "BUG: TheType does not typecheck", copy TT TT1, coq.gref->id {coq.term->gref TheType} Name, (@pi-parameter Name TT1 t\ (copy TheType t :- !) => std.map Factories (std.map-triple (=) (x\ std.map x (copy-pack-holes TheType t)) (copy-pack-holes TheType t)) (R t)), ]. :index (1) func copy-pack-holes term, term, term -> term. copy-pack-holes TheType NewType Term Out :- std.do! [ (pi Args NewArgs CSInstance ParamsRev ParamsRevCopy Pack \ (copy (app[global Pack | Args]) (app[global Pack | NewArgs]) :- pack? Pack _, std.rev Args [CSInstance,TheType|ParamsRev], !, std.map ParamsRev copy ParamsRevCopy, std.rev [{{ lib:elpi.hole }},NewType|ParamsRevCopy] NewArgs)) => copy Term Out, ]. func pack? gref -> classname. pack? (indc K) C :- coq.env.indc K _ _ _ KTy, prod-last-gref KTy (indt I), % TODO: use new API std.once (class-def (class C (indt I) _)). func distribute-w-params list-w-params A -> list (one-w-params A). distribute-w-params (w-params.cons N T F) L :- pi x\ distribute-w-params (F x) (L1 x), std.map (L1 x) (bind-cons N T x) L. distribute-w-params (w-params.nil N T F) L :- pi x\ std.map (F x) (bind-nil N T x) L. % Specific to one-w-params func w-params_1 one-w-params A -> A. w-params_1 X Y :- w-params.then X ignore ignore (p\ t\ triple_1) Y. func disable-id-phant term -> term. disable-id-phant T T1 :- (pi fresh fresh1 t v\ copy {{lib:@hb.id lp:t lp:v}} {{lib:@hb.id_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) => (pi fresh fresh1 t v\ copy {{lib:@hb.ignore lp:t lp:v}} {{lib:@hb.ignore_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) => copy T T1. func re-enable-id-phant term -> term. re-enable-id-phant T T1 :- (pi f1 f2 t v\ copy {{lib:@hb.id_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.id lp:t lp:v}} :- !) => (pi f1 f2 t v\ copy {{lib:@hb.ignore_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.ignore lp:t lp:v}} :- !) => copy T T1. func prod-last term -> term. prod-last (prod N S X) Y :- !, @pi-decl N S x\ prod-last (X x) Y. prod-last X X :- !. func prod-last-gref term -> gref. prod-last-gref (prod N S X) GR :- !, @pi-decl N S x\ prod-last-gref (X x) GR. prod-last-gref X GR :- coq.term->gref X GR. % saturate a type constructor with holes func saturate-type-constructor term -> term. saturate-type-constructor T ET :- coq.typecheck T TH ok, coq.count-prods TH N, coq.mk-app T {coq.mk-n-holes N} ET. math-comp-hierarchy-builder-4d8a939/HB/context.elpi000066400000000000000000000072461521677141400222170ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace context { pred declare i:factories, o:mixins, o:list term, o:term, o:list prop, o:list constant. declare FLwP MLwP Params TheKey MSL CL :- !, std.do! [ factories-provide FLwP MLwPRaw, declare.params-key MLwPRaw ParamsSection TheKey _MLwA, std.map ParamsSection triple_2 Params, declare.mixins TheKey ParamsSection MLwPRaw MLwP MSL CL ]. func declare.params-key w-params A -> list (triple id term term), term, A. declare.params-key MLwP Params TheKey Out :- !, std.do! [ if-verbose (coq.say {header} "declaring parameters and key as section variables"), declare.params MLwP Params KId KTy F, log.coq.env.add-section-variable-noimplicits KId KTy C, TheKey = global (const C), Out = F TheKey ]. pred declare.params i:w-params A, o:list (triple id term term), o:id, o:term, o:(term -> A). declare.params (w-params.cons PId PTy F) [triple PId P PTy|Params] KId KTy Out :- !, std.do! [ log.coq.env.add-section-variable-noimplicits PId PTy C, P = global (const C), declare.params (F P) Params KId KTy Out ]. declare.params (w-params.nil KId KTy F) [] KId KTy F :- !. % [declare.mixins TheType Parameters Factories Clauses] postulates a % (section) context with all the mixins provided by the factories and all % the structure instances we can derive on TheType from these. Clauses % contain mixin-src for each postulated mixin :index (1) func declare.mixins term, list (triple id term term), mixins -> mixins, list prop, list constant. declare.mixins TheType TheParamsSection MLwPRaw MLwP MSL CL :- std.do! [ if-verbose (coq.say "Here is the list of mixins to declare (the order matters): " {list-w-params_list MLwPRaw}), std.map TheParamsSection triple_2 TheParams, apply-w-params MLwPRaw TheParams TheType MLwAllArgsRaw, std.fold MLwAllArgsRaw (triple [] [] []) (private.postulate-mixin TheType) (triple CL MSL MLwPRev), acc-clauses current {std.map CL (cs\r\ r = local-canonical cs)}, std.rev MLwPRev MLwPSection, build-list-w-params TheParamsSection TheType MLwPSection MLwP, acc-clauses current MSL, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { % Given a type T, a fresh number N, and a mixin M it postulates % a variable "mN" inhabiting M applied to T and % all its dependencies, previously postulated and associated % to the corresponding mixin using mixin-for :index (1) func postulate-mixin term, w-args mixinname, triple (list constant) (list prop) (list (w-args mixinname)) -> triple (list constant) (list prop) (list (w-args mixinname)). postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|MSL] [NewMwP|MLwP]) :- MSL => std.do! [ Name is "local_mixin_" ^ {gref->modname M 2 "_"}, if-verbose (coq.say "HB: postulate" Name "on" {coq.term->string T}), synthesis.infer-all-gref->deps Ps T M TySkel, % was synthesis.infer-all-mixin-args Ps T M TySkel, % if-verbose (coq.say "HB: postulate-mixin checking" TySkel), % std.assert-ok! (coq.typecheck Ty _) "postulate-mixin: Ty illtyped", std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "postulate-mixin: Ty illtyped", log.coq.env.add-section-variable-noimplicits Name Ty C, factory? Ty NewMwP, MC = mixin-src T M (global (const C)), MC => get-option "local" tt => instance.declare-all TheType {findall-classes-for [M]} NewCSL, std.map NewCSL snd NewCL, std.append CL NewCL OutCL ]. }} math-comp-hierarchy-builder-4d8a939/HB/export.elpi000066400000000000000000000101611521677141400220420ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ func export.any id ->. export.any S :- coq.locate-all S L, if (L = []) (coq.error "HB: cannot locate" S) true, if (L = [X]) (export.any.aux S X) (coq.error "HB:" S "is ambiguous:" L). func export.any.aux id, located ->. export.any.aux S (loc-gref GR) :- export.abbrev S GR, !. export.any.aux S (loc-modpath MP) :- export.module S MP, !. export.any.aux S X :- coq.error "HB:" S "denotes" X "which is not supported for exporting". % [export.module Module] exports a Module now adds it to the collection of % modules to export in the end of the current enclosing module, % by the command HB.Exports % CAVEAT: "module" is a keyword, we put it in the namespace by hand func export.module id, modpath ->. export.module NiceModule Module :- !, log.coq.env.export-module NiceModule Module, coq.env.current-library File, acc-clause current (module-to-export File NiceModule Module). func export.abbrev id, gref ->. export.abbrev NiceName GR :- !, coq.env.current-library File, acc-clause current (abbrev-to-export File NiceName GR). func export.clause prop ->. export.clause Clause :- !, coq.env.current-library File, acc-clauses current [Clause, clause-to-export File Clause]. func export.reexport-all-modules-and-CS option string ->. export.reexport-all-modules-and-CS Filter :- std.do! [ coq.env.current-library File, export.private.compute-filter Filter MFilter, if-verbose (coq.say {header} "exporting under the module path" MFilter), % NODE: std.list-uniq is for coq < 8.13 std.findall (module-to-export File NiceModule_ Module_) ModsCL, std.filter {std.list-uniq ModsCL} (export.private.module-in-module MFilter) ModsCLFiltered, std.map ModsCLFiltered module-to-export_module-nice NiceMods, std.map ModsCLFiltered module-to-export_module Mods, if-verbose (coq.say {header} "exporting modules" NiceMods), std.forall2 NiceMods Mods log.coq.env.export-module, std.findall (instance-to-export File NiceInstance_ Const_) InstCL, std.filter {std.list-uniq InstCL} (export.private.instance-in-module MFilter) InstCLFiltered, std.map InstCLFiltered instance-to-export_instance Insts, if-verbose (coq.say {header} "exporting CS instances" Insts), std.forall Insts log.coq.CS.declare-instance, std.findall (abbrev-to-export File NiceAbbrev_ GR_) InstAbbL, std.filter {std.list-uniq InstAbbL} (export.private.abbrev-in-module MFilter) InstAbbLFiltered, std.map InstAbbLFiltered abbrev-to-export_name AbbNames, std.map InstAbbLFiltered abbrev-to-export_body AbbBodies, if-verbose (coq.say {header} "exporting Abbreviations" AbbNames), std.forall2 AbbNames AbbBodies (n\b\@global! => log.coq.notation.add-abbreviation n 0 b ff _), std.findall (clause-to-export File Clause_) ClausesL, if-verbose (coq.say {header} "exporting Clauses" Clauses), std.map ClausesL clause-to-export_clause Clauses, acc-clauses current Clauses ]. namespace export.private { :index (1) func prefixL list A, list A ->. prefixL [] _. prefixL [X|Xs] [X|Ys] :- prefixL Xs Ys. func abbrev-in-module list string, prop ->. abbrev-in-module PM (abbrev-to-export _ _ GR) :- coq.gref->path GR PC, prefixL PM PC. func module-in-module list string, prop ->. module-in-module PM (module-to-export _ _ M) :- coq.modpath->path M PC, prefixL PM PC. func instance-in-module list string, prop ->. instance-in-module PM (instance-to-export _ _ C) :- coq.gref->path (const C) PC, prefixL PM PC. func compute-filter option string -> list string. compute-filter none []. compute-filter (some S) MFilter :- % S is a component of the current modpath coq.env.current-path P, rex_split "\\." S L, compute-filter.aux P L MFilter, !. compute-filter (some S) MFilter :- coq.locate-module S M, coq.modpath->path M MFilter. % @gares: same predicate in synterp: code clone? func compute-filter.aux list string, list string -> list string. compute-filter.aux [S|_] [S] [S] :- !. compute-filter.aux [S|XS] [S|SS] [S|YS] :- !, compute-filter.aux XS SS YS. compute-filter.aux [X|XS] L [X|YS] :- compute-filter.aux XS L YS. } math-comp-hierarchy-builder-4d8a939/HB/factory.elpi000066400000000000000000000457401521677141400222030ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace factory { func declare argument ->. declare A :- private.declare-asset A private.asset-factory. func declare-mixin argument ->. declare-mixin A :- private.declare-asset A private.asset-mixin. kind factory-abbrev type. type by-classname gref -> factory-abbrev. type by-phantabbrev abbreviation -> factory-abbrev. :index (_ 1) func declare-abbrev id, factory-abbrev -> abbreviation. declare-abbrev Name (by-classname GR) Abbrev :- % looks fishy (the parameters are not taken into account) @global! => log.coq.notation.add-abbreviation Name 1 (fun _ _ t\ app[global GR,t]) tt Abbrev. declare-abbrev Name (by-phantabbrev Abbr) Abbrev :- coq.notation.abbreviation-body Abbr Nargs AbbrTrm, @global! => log.coq.notation.add-abbreviation Name Nargs AbbrTrm tt Abbrev. func argument->w-mixins argument -> w-mixins argument. argument->w-mixins (indt-decl Decl) (pr MLwP ArgwP) :- !, std.do! [ pdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = indt-decl x) ArgwP ]. argument->w-mixins (const-decl Id none Decl) (pr MLwP ArgwP) :- !, std.do! [ pdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = const-decl Id none x) ArgwP, ]. argument->w-mixins (const-decl Id (some Body) Decl as CDecl) (pr MLwP ArgwP) :- !, std.do! [ if-verbose (coq.say {header} "arguments->w-mixins on const-decl Decl=" CDecl), pdecl->w-mixins Decl (pr MLwP DeclwP), if-verbose (coq.say {header} "arguments->w-mixins on const-decl Decl=" Decl "\nwith MLwP =" MLwP), std.length {list-w-params_list MLwP} NML, if-verbose (coq.say "ML length =" NML), w-params.map DeclwP (ps\ t\ x\ y\ sigma Dummies Args AppBody\ std.do! [ std.nlist NML (sort prop) Dummies, std.append ps [t|Dummies] Args, coq.subst-fun Args Body AppBody, y = const-decl Id (some AppBody) x]) ArgwP ]. argument->w-mixins (ctx-decl Decl) (pr MLwP ArgwP) :- !, std.do! [ cdecl->w-mixins Decl (pr MLwP DeclwP), w-params.map DeclwP (_\ _\ x\ y\ y = ctx-decl x) ArgwP ]. func argument-name argument -> string. argument-name (const-decl Id _ _) Id. argument-name (indt-decl (parameter _ _ _ R)) Id :- argument-name (indt-decl (R (sort prop))) Id. argument-name (indt-decl (record Id _ _ _)) Id. argument-name (indt-decl (inductive Id _ _ _)) Id. argument-name (ctx-decl _) "_" :- !. func pdecl->w-mixins indt-decl -> w-mixins indt-decl. pdecl->w-mixins ((parameter ID _ TySkel Rest : indt-decl) as Decl) Out :- private.is-key Decl, !, private.key-decl-w-mixins "parameter" ID TySkel Rest private.pdecl->w-mixins.mixins Out. pdecl->w-mixins (parameter ID _ TySkel Rest : indt-decl) Out :- !, private.param-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins Out. pdecl->w-mixins (_ : indt-decl) _ :- !, coq.error "HB: declaration must have at least one parameter". func pdecl->w-mixins arity -> w-mixins arity. pdecl->w-mixins ((parameter ID _ TySkel Rest : arity) as Decl) (Out:w-mixins arity) :- private.is-key Decl, !, private.key-decl-w-mixins "parameter" ID TySkel Rest private.pdecl->w-mixins.mixins Out. pdecl->w-mixins (parameter ID _ TySkel Rest : arity) (Out:w-mixins arity) :- !, private.param-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins Out. pdecl->w-mixins (_ : arity) _ :- !, coq.error "HB: declaration must have at least one parameter". func cdecl->w-mixins context-decl -> w-mixins context-decl. cdecl->w-mixins (context-item _ _ _ (some _) _) _ :- !, coq.error "HB: local definition is not supported in this context". cdecl->w-mixins (context-item ID _ TySkel none Rest as Decl) Out :- private.is-key Decl, !, private.key-decl-w-mixins "context-item" ID TySkel Rest private.cdecl->w-mixins.mixins Out. cdecl->w-mixins (context-item ID _ TySkel none Rest) Out :- !, private.param-decl-w-mixins "context-item" ID TySkel Rest cdecl->w-mixins Out. cdecl->w-mixins _ _ :- !, coq.error "HB: declaration must have at least one parameter". /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. % Type to share code between HB.mixin and HB.factory e(that supports alias factories) kind asset type. type asset-mixin asset. type asset-factory asset. func check-key-attribute-consistency id ->. check-key-attribute-consistency _ :- not(get-option "key" _), !. check-key-attribute-consistency ID :- get-option "key" ID, !. check-key-attribute-consistency ID :- get-option "key" ID1, !, coq.error "HB:" {calc ("The #[key=\"" ^ ID1 ^ "\"] attribute")} "does not match the selected subject" ID. func is-key indt-decl ->. is-key (parameter ID _ _ _\ record _ _ _ _ : indt-decl) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _\ inductive _ _ _ _ : indt-decl) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _ : indt-decl) :- get-option "key" ID, !. is-key (parameter ID _ _ p\ parameter _ _ (M p) _ : indt-decl) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func is-key arity ->. is-key (parameter ID _ _ _\ arity _ : arity) :- !, check-key-attribute-consistency ID. is-key (parameter ID _ _ _ : arity) :- get-option "key" ID, !. is-key (parameter ID _ _ p\ parameter _ _ (M p) _ : arity) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func is-key context-decl ->. is-key ((context-item ID _ _ _ _\ context-end) : context-decl) :- !, check-key-attribute-consistency ID. is-key (context-item ID _ _ _ _ : context-decl) :- get-option "key" ID, !. is-key (context-item ID _ _ _ p\ context-item _ _ (M p) _ _ : context-decl) :- pi p\ factory? (M p) _, !, check-key-attribute-consistency ID. func mixin-decl-w-mixins string, string, term, (term -> A), (pred i:A, o:pair (list (w-args mixinname)) A) -> pair (list (w-args mixinname)) A. mixin-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- std.do! [ if-verbose (coq.say {header} "processing mixin" DeclKind ID), std.assert! (not (var TySkel)) "HB: no type provided for mixin", disable-id-phant TySkel TySkelNoId, std.assert-ok! (coq.elaborate-ty-skeleton TySkelNoId _ TyNoId) "HB: mixin illtyped", re-enable-id-phant TyNoId Ty, std.assert! (factory? Ty (triple F Ps T)) "HB: Not a factory applied to the key variable", std.assert! (pi x y\ Rest y = Rest x) "HB: Factories cannot be explicitly mentioned in the subsequent declaration", Dummy = sort prop, Conv (Rest Dummy) (pr MLwA R), Out = pr [triple F Ps T|MLwA] R ]. :index(1) func key-decl-w-mixins string, string, term, (term -> A), (pred i:A, o:pair (list (w-args mixinname)) A) -> pair mixins (w-params A). key-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- std.do! [ if-verbose (coq.say {header} "processing key" DeclKind), std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "key illtyped", coq.string->name ID N, @pi-decl N Ty t\ Conv (Rest t) (pr (MLwA t) (R t)), if (var Ty) (fresh-type Ty) true, Out = pr (w-params.nil ID Ty MLwA) (w-params.nil ID Ty R) ]. :index (1) func param-decl-w-mixins string, string, term, (term -> A), (func A -> pair mixins (w-params A)) -> pair mixins (w-params A). param-decl-w-mixins DeclKind ID TySkel Rest Conv Out :- if-verbose (coq.say {header} "processing param" DeclKind), std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty) "param illtyped", coq.string->name ID N, @pi-decl N Ty p\ Conv (Rest p) (pr (MLwP p) (R p)), if (var Ty) (fresh-type Ty) true, Out = pr (w-params.cons ID Ty MLwP) (w-params.cons ID Ty R). func pdecl->w-mixins.mixins indt-decl -> pair (list (w-args mixinname)) indt-decl. pdecl->w-mixins.mixins (parameter ID _ TySkel Rest : indt-decl) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins.mixins Out. pdecl->w-mixins.mixins (R : indt-decl) (pr [] R) :- !. func pdecl->w-mixins.mixins arity -> pair (list (w-args mixinname)) arity. pdecl->w-mixins.mixins (parameter ID _ TySkel Rest : arity) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest pdecl->w-mixins.mixins Out. pdecl->w-mixins.mixins (R : arity) (pr [] R) :- !. func cdecl->w-mixins.mixins context-decl -> pair (list (w-args mixinname)) context-decl. cdecl->w-mixins.mixins context-end (pr [] context-end) :- !. cdecl->w-mixins.mixins (context-item _ _ _ (some _) _) _ :- !, coq.error "HB: local definition is not supported in this context". cdecl->w-mixins.mixins (context-item ID _ TySkel none Rest) Out :- !, mixin-decl-w-mixins "parameter" ID TySkel Rest cdecl->w-mixins.mixins Out. % The identity builder func declare-id-builder factoryname -> prop. declare-id-builder GR (from GR GR (const C)) :- std.do! [ gref->deps GR GRD, synthesis.mixins-w-params.fun GRD (declare-id-builder.aux GR) IDBodySkel, std.assert-ok! (coq.elaborate-skeleton IDBodySkel IDType IDBody) "identity builder illtyped", log.coq.env.add-const-noimplicits "identity_builder" IDBody IDType @transparent! C, ]. declare-id-builder.aux GR Params TheType (fun `x` Ty x\x) :- synthesis.infer-all-gref->deps Params TheType GR Ty. % [mk-factory-abbrev Str GR CL FactAbbrev] % creates an abbreviation for GR names Str and creates a phant-abbrev clause in CL. % FactAbbrev is the short name for the factory (either an alias of the class record) func mk-factory-abbrev string, gref -> list prop, factory-abbrev. mk-factory-abbrev Str GR Aliases FactAbbrev :- if (factory-alias->gref GR _ ok) (Aliases = [], FactAbbrev = by-classname GR) (phant.of-gref ff GR [] PhTerm, phant.add-abbreviation Str PhTerm PhC Abbrv, Aliases = [phant-abbrev GR (const PhC) Abbrv], FactAbbrev = by-phantabbrev Abbrv). % [declare-asset Asset AssetKind] unifies the code paths for % mixins, factories (and alias factories) func declare-asset argument, asset ->. declare-asset Arg AssetKind :- std.do! [ argument-name Arg Module, if-verbose (coq.say {header} "start module and section" Module), log.coq.env.begin-module Module none, log.coq.env.begin-section Module, if-verbose (coq.say {header} "converting arguments" Arg "to factories"), argument->w-mixins Arg (pr FLwP ArgwP), if-verbose (coq.say {header} "converting factories" FLwP "to mixins"), %%% factories-provide FLwP MLwP, if-verbose (coq.say {header} "declaring context" FLwP), context.declare FLwP MLwP Params TheKey MixinSrcClauses SectionCanonicalInstance, if (Arg = indt-decl _) ( apply-w-params ArgwP Params TheKey (indt-decl (record _ Sort _ Fields)), if-verbose (coq.say {header} "declare mixin or factory"), declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance Params TheKey Sort Fields MLwP Module AssetKind ) ( apply-w-params ArgwP Params TheKey (const-decl _ (some Sort) _), if-verbose (coq.say {header} "declare factory alias"), declare-factory-alias MixinSrcClauses SectionCanonicalInstance Params TheKey Sort MLwP Module ) ]. pred declare-mixin-or-factory i:list prop, i:list constant, i:list term, i:term, i:term, i:record-decl, i:list-w-params factoryname, i:id, i:asset. declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance TheParams TheType Sort1 Fields GRFSwP Module D :- std.do! [ if-verbose (coq.say {header} "declare record axioms_"), Kname = "Axioms_", RDeclSkel = record "axioms_" Sort1 Kname Fields, std.assert-ok! (coq.elaborate-indt-decl-skeleton RDeclSkel RDecl) "record declaration illtyped", abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-indt-decl RDecl RDeclClosed _, if (get-option "primitive" tt) (@primitive! => log.coq.env.add-indt RDeclClosed R) (log.coq.env.add-indt RDeclClosed R), log.coq.env.end-section-name Module, % We need to anyway declare the record inside the section % since closing the section purges the unused universe level we may have % allocated by typechecking the skeleton just above coq.env.indt R tt _ _ _ [K] _, GRK = indc K, @global! => log.coq.arguments.set-implicit (indt R) [[]], @global! => log.coq.arguments.set-implicit GRK [[]], factories-provide GRFSwP MLwP, w-params.nparams MLwP NParams, build-deps-for-projections R MLwP GRDepsClausesProjs, GRDepsClauses = [gref->deps (indt R) MLwP, gref->deps (indc K) MLwP|GRDepsClausesProjs], % GRDepsClauses => mk-factory-sort MLwP (indt R) _ FactorySortCoe, % FactorySortCoe = coercion GRFSort _ _ _, % TODO: should this be in the Exports module? if-verbose (coq.say {header} "declare notation Build"), GRDepsClauses => phant.of-gref ff GRK [] PhGRK, GRDepsClauses => phant.add-abbreviation "Build" PhGRK BuildConst BuildAbbrev, if-verbose (coq.say {header} "declare notation axioms"), if (D = asset-mixin) ((GRDepsClauses => mk-factory-abbrev "axioms" (indt R) FRClauses FactAbbrev), (GRDepsClauses => FRClauses => declare-id-builder (indt R) IdBuilderClause), Clauses = [IdBuilderClause|FRClauses]) (GRDepsClauses => mk-factory-abbrev "axioms" (indt R) Clauses FactAbbrev), if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, std.flatten [Clauses, GRDepsClauses, [ is-factory (indt R), factory->constructor (indt R) GRK, factory->nparams (indt R) NParams, phant-abbrev GRK (const BuildConst) BuildAbbrev, % gref->deps GRFSort MLwP, % factory-sort FactorySortCoe, ]] NewClauses, acc-clauses current NewClauses, list-w-params_list MLwP MLwoP, std.map MLwoP (_\ r\ r = maximal) Implicits, /* std.map {list-w-params_list MLwP} (_\ r\ r = maximal) Implicits, */ @global! => log.coq.arguments.set-implicit GRK [[maximal|Implicits]], % @global! => log.coq.coercion.declare FactorySortCoe, log.coq.env.end-module-name "Exports" Exports, log.coq.env.end-module-name Module _, if-verbose (coq.say {header} "end modules and sections; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, GRDepsClauses => declare-abbrev Module FactAbbrev _, ]. :index (1) func declare-factory-alias list prop, list constant, list term, term, term, list-w-params factoryname, id. declare-factory-alias MixinSrcClauses SectionCanonicalInstance TheParams TheType Ty1Skel GRFSwP Module :- std.do! [ if-verbose (coq.say {header} "declare constant axioms_"), std.assert-ok! (coq.elaborate-ty-skeleton Ty1Skel _ Ty1) "Illtyped alias factory", abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-const-decl (pr Ty1 _) (pr Ty1Closed _) Section, log.coq.env.add-const-noimplicits "axioms_" Ty1Closed _ @transparent! C, std.assert! (safe-dest-app Ty1 (global PhF) _Args) "Argument must be a factory", std.assert-ok! (factory-alias->gref PhF F) "HB", std.assert! (factory->constructor F FK) "BUG: Factory constructor missing", MixinSrcClauses => synthesis.infer-all-gref->deps TheParams TheType FK MFK, std.assert-ok! (coq.typecheck MFK MFKTy) "BUG: typecking of former factory constructor failed", (pi Args\ copy (app[global F|Args]) (app[global (const C)|Section])) => copy MFKTy MFKTyC, abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance coq.abstract-const-decl (pr MFK MFKTyC) (pr MFKClosed MFKTyCClosed) _, log.coq.env.add-const-noimplicits "Axioms_" MFKClosed MFKTyCClosed @transparent! CK, GRK = const CK, log.coq.env.end-section-name Module, @global! => log.coq.arguments.set-implicit GRK [[]], factories-provide GRFSwP MLwP, GRDepsClauses = [gref->deps (const C) MLwP, gref->deps (const CK) MLwP], GRDepsClauses => phant.of-gref ff GRK [] PhGRK0, % GRDepsClauses => mk-factory-sort MLwP (const C) _ FactorySortCoe, % FactorySortCoe = coercion GRFSort _ _ _, if (mixin->first-class F _) (PhGRK = PhGRK0) (phant.append-fun-unify PhGRK0 PhGRK), GRDepsClauses => phant.add-abbreviation "Build" PhGRK _ _, GRDepsClauses => mk-factory-abbrev "axioms" (const C) Clauses FactAbbrev, if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, w-params.nparams MLwP NParams, std.flatten [ Clauses, GRDepsClauses, [ is-factory (const C), factory->nparams (const C) NParams, factory->constructor (const C) GRK, % gref->deps GRFSort MLwP, % factory-sort FactorySortCoe ] ] NewClauses, acc-clauses current NewClauses, %@global! => log.coq.coercion.declare FactorySortCoe, log.coq.env.end-module-name "Exports" Exports, log.coq.env.end-module-name Module _, if-verbose (coq.say {header} "end modules and sections; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, GRDepsClauses => declare-abbrev Module FactAbbrev _, ]. % [build-deps-for-projections I ML CL] builds a [gref-dep] for each projection P % of I such that P depends on "ML @ [I]" (each operation depends on the the % deps of the record plus the record itself) func build-deps-for-projections inductive, mixins -> list prop. build-deps-for-projections R MLwP CL :- std.do! [ compat.map-filter {coq.env.projections R} (x\y\x = some y) MixinOps, list-w-params.rcons MLwP (pl\t\r\ r = triple (indt R) pl t) MLRwP, std.map MixinOps (gr\r\ r = gref->deps (const gr) MLRwP) CL, ]. % Section handling in Coq is smart, in the sense it it only abstracts over % variables that aoccur. We don't want that for mixin/factories, so we implement % our own discharging. Note that definitions (like canonical instance) have % to be abstracted too. :index (1) func abstract-over-section list term, term, list prop, list constant, (func list constant, A -> A), A -> A, list term. abstract-over-section TheParams TheType MixinSrcClauses SectionCanonicalInstance F X X1 Section :- % compute section variables to be used for discharging std.map MixinSrcClauses mixin-src_src Mixins, std.append TheParams [TheType|{std.rev Mixins}] Section, std.map Section (x\r\ x = global (const r)) SectionVars, % We discharge by hand the record declaration so that we can be sure all % parameters and mixins are abstracted (even if unused). coq.copy-clauses-for-unfold SectionCanonicalInstance CopyUnfold, CopyUnfold => F SectionVars X X1. func mk-factory-sort mixins, gref -> gref, coercion. mk-factory-sort MLwP GR (const FactorySortCst) Coe :- if-verbose (coq.say {header} "declaring tagged sort for GR=" GR), synthesis.mixins-w-params.fun MLwP (mk-factory-sort.term GR) FactorySort, std.assert-ok! (coq.typecheck FactorySort FactorySortTy) "HB: cannot elaborate sort", log.coq.env.add-const-noimplicits "sort" FactorySort FactorySortTy ff FactorySortCst, synthesis.mixins-w-params.length MLwP MLwPLength, std.nlist {calc (MLwPLength + 1)} implicit MLwPImplicits, (@global! => log.coq.arguments.set-implicit (const FactorySortCst) [MLwPImplicits]), synthesis.infer-coercion-tgt MLwP CoeClass, Coe = coercion (const FactorySortCst) MLwPLength GR CoeClass. func mk-factory-sort.term gref, list term, term -> term. mk-factory-sort.term GR P T (fun `_` Ty _\ T) :- synthesis.infer-all-gref->deps P T GR Ty. }}math-comp-hierarchy-builder-4d8a939/HB/graph.elpi000066400000000000000000000016721521677141400216310ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace graph { func to-file string ->. to-file File :- !, std.do! [ open_out File OC, output OC "digraph Hierarchy { ", std.forall {coq.coercion.db} (private.pp-coercion-dot OC), output OC "}", close_out OC, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { func pp-coercion-dot out_stream, coercion ->. pp-coercion-dot OC (coercion _ _ Src (grefclass Tgt)) :- class-def (class Src _ _), class-def (class Tgt _ _), !, std.do! [ output OC {gref->modname_short Tgt "_"}, output OC " -> ", output OC {gref->modname_short Src "_"}, output OC ";\n", ]. pp-coercion-dot _ _. }}math-comp-hierarchy-builder-4d8a939/HB/howto.elpi000066400000000000000000000160671521677141400216740ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace howto { :index (1) func main-trm term, string, option int ->. main-trm T STgt Depth :- coq.term->gref T GR, main-gref GR STgt Depth. :index (1) func main-str string, string, option int ->. main-str S STgt Depth :- coq.locate S GR, main-gref GR STgt Depth. :index (1) func main-gref gref, string, option int ->. main-gref GR STgt Depth :- class-def (class _ GR _), !, private.mixins-in-structures [GR] MLSrc, main-from MLSrc STgt Depth. main-gref GR STgt Depth :- private.structures-on-gref GR SL, private.mixins-in-structures SL MLSrc, main-from MLSrc STgt Depth. :index (1) func main-from list mixinname, string, option int ->. main-from MLSrc STgt Depth :- private.mixins-in-structures [{coq.locate STgt}] MLTgt, private.list-diff MLTgt MLSrc ML, if (ML = []) (coq.say "HB: nothing to do.") (main-from.aux MLSrc ML Depth). :index (_ _ 1) func main-from.aux list mixinname, list mixinname, option int ->. main-from.aux MLSrc ML (some Depth) :- main-increase-depth MLSrc ML Depth false. main-from.aux MLSrc ML none :- main-increase-depth MLSrc ML 3 true. :index (1) func main-increase-depth list mixinname, list mixinname, int, prop. main-increase-depth MLSrc ML Depth AutoIncrease :- private.paths-from-for-step MLSrc ML Depth R, if (not (R = [])) (private.pp-solutions R) (if AutoIncrease (Depth' is Depth + 1, coq.say "HB: no solution found at depth" Depth "looking at depth" Depth', main-increase-depth MLSrc ML Depth' true) (coq.error "HB: no solution found, try to increase search depth.")). /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.pp.{ v , hov , spc , str , box , glue }. % L1 \subseteq L2 func incl list A, list A ->. incl L1 L2 :- std.forall L1 (std.mem! L2). % R = L1 \ L2 func list-diff list A, list A -> list A. list-diff L1 L2 R :- std.filter L1 (about.not1 (std.mem L2)) R. % R = L1 U L2 func union list A, list A -> list A. union L1 L2 R :- std.fold L2 L1 (x\l\l'\if (std.mem l x) (l' = l) (l' = [x|l])) R. func insert-sorted (func A, A ->), A, list A -> list A. insert-sorted _ X [] [X] :- !. insert-sorted Rel X [Y|T] [X,Y|T] :- Rel X Y, !. insert-sorted Rel X [Y|T] [Y|T'] :- insert-sorted Rel X T T', !. func lt-gref gref, gref. lt-gref X Y :- gref->modname_short X "." SX, gref->modname_short Y "." SY, !, SX s< SY. pred size-order i:(func list A, list A), i:list A, i:list A. size-order Rel L1 L2 :- std.length L1 S1, std.length L2 S2, !, (S1 i< S2; (S1 = S2, !, Rel L1 L2)). pred lexi-order i:list gref, i:list gref. lexi-order [] []. lexi-order [X1|_] [X2|_] :- lt-gref X1 X2. lexi-order [X|T1] [X|T2] :- lexi-order T1 T2. % [structures-on-gref GR ML] list structures [GR] is equipped with func structures-on-gref gref -> list structure. structures-on-gref GR SL :- std.filter {coq.CS.db-for _ (cs-gref GR)} (about.not1 about.unif-hint?) LV, std.map LV structures-on-gref.aux SL. func structures-on-gref.aux cs-instance -> structure. structures-on-gref.aux (cs-instance _ _ GR) F :- coq.prod-tgt->gref {coq.env.typeof GR} F, std.once (class-def (class _ F _)). % [mixins-in-structures SL ML] list mixins in structures [SL] func mixins-in-structures list structure -> list mixinname. mixins-in-structures SL ML :- std.fold SL [] mixins-in-structures.aux ML. func mixins-in-structures.aux structure, list mixinname -> list mixinname. mixins-in-structures.aux F L L' :- std.once (class-def (class _ F MLWP)), union L {list-w-params_list MLWP} L'. % a type to store a factory along with the mixins it depends on % and the mixins it provides kind factory_deps_prov type. type fdp factoryname -> list mixinname -> list mixinname -> factory_deps_prov. % get all available factories in the above type func list_factories -> list factory_deps_prov. list_factories FL :- std.map-filter {findall-factory->constructor} list_factories.aux FL. func list_factories.aux prop -> howto.private.factory_deps_prov. list_factories.aux (factory->constructor F _) (fdp F DML PML) :- gref->deps F FD, list-w-params_list FD DML, list-w-params_list {factory-provides F} PML. % [paths-from-for-step MLSrc ML K R] returns in [R] a list of sequences % of at most [K] factories that could, starting from mixins [MLSrc], % build exactly the mixins [ML] func paths-from-for-step list mixinname, list mixinname, int -> list (list factoryname). paths-from-for-step MLSrc ML K R :- std.filter {list_factories} (fd\sigma pml\fd = fdp _ _ pml, incl pml ML) FL, paths-from-for-step-using MLSrc ML K [] [] FL _ R. % [paths-from-for-step-using MLSrc ML K Pre KnownPre FL KnownPre' R] % same as [paths-from-for-step MLSrc ML K R] using only factories in [FL] % [Pre] is a (sorted) prefix that is looked into the list of known (sorted) % prefixes [KnownPre] to avoid generating identical solutions up to permutations :index (1) func paths-from-for-step-using list mixinname, list mixinname, int, list factoryname, list (list factoryname), list factory_deps_prov -> list (list factoryname), list (list factoryname). paths-from-for-step-using _ _ K _ KnownPre _ KnownPre [] :- K i< 0, !. paths-from-for-step-using _ _ _ Pre KnownPre _ KnownPre [] :- std.mem KnownPre Pre, !. paths-from-for-step-using _ [] _ Pre KnownPre _ [Pre|KnownPre] [[]] :- !. paths-from-for-step-using MLSrc ML K Pre KnownPre FL [Pre|KnownPre'] R :- K' is K - 1, std.filter FL (p\sigma dml\p = fdp _ dml _, incl dml MLSrc) FLdep, std.fold FLdep (pr KnownPre []) (paths-from-for-step-using.aux MLSrc ML FL K' Pre) (pr KnownPre' R). func paths-from-for-step-using.aux list mixinname, list mixinname, list factory_deps_prov -> int, list factoryname, factory_deps_prov, pair (list (list factoryname)) (list (list factoryname)), pair (list (list factoryname)) (list (list factoryname)). paths-from-for-step-using.aux MLSrc ML FL' K' Pre (fdp F _ MLF) (pr KnPre L) (pr KnPre' R) :- std.append MLSrc MLF MLSrc', list-diff ML MLF ML', insert-sorted lt-gref F Pre Pre', std.filter FL' (p\sigma pml\p = fdp _ _ pml, incl pml ML') FML', paths-from-for-step-using MLSrc' ML' K' Pre' KnPre FML' KnPre' R', std.map R' (l\r\r = [F|l]) R'', std.append L R'' R. func pp-solutions list (list factoryname) ->. pp-solutions LLF :- std.sort LLF (size-order lexi-order) SLLF, % format PpSolutions = box (v 4) [ str "HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F):", {about.bulletize SLLF pp-solution}], % print coq.say {coq.pp->string PpSolutions}, coq.say, coq.say "For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances", coq.say. func pp-solution list factoryname -> coq.pp. pp-solution L (box (hov 0) PLS) :- std.map L about.pp-module PL, std.intersperse (glue [str ";", spc]) PL PLS. }}math-comp-hierarchy-builder-4d8a939/HB/instance.elpi000066400000000000000000000500571521677141400223350ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace instance { % [declare-existing T F] equips T with all the canonical structures that can be % built using factory instance F func declare-existing argument, argument ->. declare-existing T0 F0 :- std.do! [ argument->ty T0 T, % TODO: change this when supporting morphism hierarchies argument->term F0 F, std.assert-ok! (coq.typecheck F FTy) "HB: declare-existing illtyped factory instance", std.assert! (coq.safe-dest-app FTy (global FactoryAlias) _) "The type of the instance is not a factory", std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB: ", private.declare-instance Factory T F Clauses _ _, acc-clauses current Clauses, ]. % [declare-const N B Ty CFL CSL] adds a Definition N : Ty := B where Ty is a factory % and equips the type the factory is used on with all the canonical structures % that can be built using factory instance B. CFL contains the list of % factories being defined, CSL the list of canonical structures being defined. func declare-const id, term, arity -> list (pair id constant), list (pair id constant). declare-const Name BodySkel TyWPSkel CFL CSL :- std.do! [ std.assert-ok! (coq.elaborate-arity-skeleton TyWPSkel _ TyWP) "Definition type illtyped", coq.arity->term TyWP Ty, std.assert-ok! (coq.elaborate-skeleton BodySkel Ty Body) "Definition illtyped", % handle parameters via a section -- begin if (TyWP = arity SectionTy) ( % Do not open a section when it is not necessary (no parameters) % A side effect of opening a section is loosing meta data associated % with instances, in particular builder tags are lost if-verbose (coq.say "HB: skipping section opening"), SectionBody = Body ) ( std.assert! (coq.next-synterp-action (begin-section SectionName)) "synterp code did not open section", log.coq.env.begin-section SectionName, private.postulate-arity TyWP [] Body SectionBody SectionTy ), % identify the factory std.assert! (coq.safe-dest-app SectionTy (global FactoryAlias) Args) "The type of the instance is not a factory", std.assert-ok! (factory-alias->gref FactoryAlias Factory) "HB", std.assert! (factory->nparams Factory NParams) "Not a factory synthesized by HB", % declare the constant for the factory instance private.hack-section-discharging SectionBody SectionBodyHack, private.optimize-body SectionBodyHack OptimizedBody, if (Name = "_") (RealName is "HB_unnamed_factory_" ^ {std.any->string {new_int} }) (RealName = Name), % unfold local instances in the type of C if (current-mode (builder-from _ _ _ _)) (std.do![ findall-local-canonical LocalCSL, coq.copy-clauses-for-unfold LocalCSL UnfoldClauses, UnfoldClauses => copy SectionTy SectionTyUnfolded, ]) (SectionTy = SectionTyUnfolded), % call HB.instance TheType TheFactory std.drop NParams Args [TheType|_], if (var TheType) (coq.error "HB: The instance subject must be explicitly given.\nUse:\n HB.instance Definition _ : M := ...\n HB.instance Definition _ := M.Build ...") true, log.coq.env.add-const-noimplicits-failondup RealName OptimizedBody SectionTyUnfolded @transparent! C, TheFactory = (global (const C)), private.check-non-forgetful-inheritance TheType Factory, private.declare-instance Factory TheType TheFactory Clauses CFL CSL, if (CSL = []) (coq.warning "HB" "HB.no-new-instance" "HB: no new instance is generated") true, % handle parameters via a section -- end if (TyWP = arity _) true ( if-verbose (coq.say {header} "closing instance section"), log.coq.env.end-section-name SectionName ), % we accumulate clauses now that the section is over acc-clauses current Clauses ]. % [not-subclass-of X C] holds if C does not inherit from X func not-subclass-of classname, hbclass ->. not-subclass-of HasNoInstance (class C _ _) :- not(sub-class C HasNoInstance _ _). % [declare-all T CL MCSTL] given a type T and a list of class definition % CL in topological order (from least dep to most) looks for classes % for which all the dependencies (mixins) were postulated so far and skips the % rest. For each fulfilled class it declares a local constant inhabiting the % corresponding structure and declares it canonical. % Each mixin used in order to fulfill a class is returned together with its name. func declare-all term, list hbclass -> list (pair id constant). declare-all _ [] []. declare-all T [class _ Struct _|Rest] L :- has-instance T Struct, !, declare-all T Rest L. declare-all T [class Class Struct MLwP|Rest] [pr Name CS|L] :- infer-class T Class Struct MLwP S Name STy Clauses, !, decl-const-in-struct Name S STy CS, Clauses => declare-all T Rest L. declare-all T [class HasNoInstance _ _|Rest] L :- % filter out classes we can't build for sure std.filter Rest (not-subclass-of HasNoInstance) Rest1, declare-all T Rest1 L. % for generic types, we need first to instantiate them by giving them holes, % so they can be used to instantiate the classes :index (_ 2) func declare-all-on-type-constructor term, list hbclass -> list (pair id constant). declare-all-on-type-constructor _ [] []. declare-all-on-type-constructor TK [class _ Struct _|Rest] L :- saturate-type-constructor TK T, has-instance T Struct, !, declare-all-on-type-constructor TK Rest L. declare-all-on-type-constructor TK [class Class Struct MLwP|Rest] [pr Name CS|L] :- %TODO: compute the arity of the Class subject and saturate up to that point % there may even be more than one possibility saturate-type-constructor TK T, infer-class T Class Struct MLwP S Name _STy Clauses, !, abstract-holes.main S SC, std.assert-ok! (coq.typecheck SC SCTy) "declare-all-on-type-constructor: badly closed", decl-const-in-struct Name SC SCTy CS, Clauses => declare-all-on-type-constructor TK Rest L. declare-all-on-type-constructor TK [class HasNoInstance _ _|Rest] L :- % filter out classes we can't build for sure std.filter Rest (not-subclass-of HasNoInstance) Rest1, declare-all-on-type-constructor TK Rest1 L. func has-instance term, structure ->. has-instance T Struct :- if (has-CS-instance? T Struct) (if-verbose (coq.say {header} "skipping already existing" {nice-gref->string Struct} "instance on" {coq.term->string T})) fail. % we build it func infer-class term, classname, gref, factories -> term, string, term, list prop. infer-class T Class Struct MLwP S Name STy Clauses:- std.do![ params->holes MLwP Params, get-constructor Class KC, if (synthesis.infer-all-args-let Params T KC KCApp ok) (if-verbose (coq.say {header} "we can build a" {nice-gref->string Struct} "on" {coq.term->string T})) fail, Name is {cs-pattern->name {term->cs-pattern T}} ^ "__canonical__" ^ {gref->modname Struct 2 "_" }, if-verbose (coq.say {header} "declare canonical structure instance" Name), get-constructor Struct KS, coq.safe-dest-app T THD _, private.optimize-class-body THD {std.length Params} KCApp KCAppNames Clauses, coq.mk-app (global KS) {std.append Params [T, KCAppNames]} S, if-verbose (coq.say {header} "structure instance for" Name "is" {coq.term->string S}), coq.typecheck S STy ok, % failure may be due to a parameter not rich enough see #435 ]. func decl-const-in-struct string, term, term, constant ->. decl-const-in-struct Name S STy CS:- std.do![ if (ground_term S) (S1 = S, STy1 = STy) (abstract-holes.main S S1, std.assert-ok! (coq.typecheck S1 STy1) "HB: structure instance illtyped after generalizing over holes"), log.coq.env.add-const-noimplicits Name S1 STy1 @transparent! CS, % Bug coq/coq#11155, could be a Let with-locality (log.coq.CS.declare-instance CS), % Bug coq/coq#11155, should be local acc-clause current (local-canonical CS), if-verbose (coq.say {header} "structure instance" Name "declared"), ]. func declare-factory-sort-deps gref ->. declare-factory-sort-deps GR :- std.do! [ if-verbose (coq.say {header} "required instances on factory sort for" GR), Name is "SortInstances" ^ {std.any->string {new_int}}, log.coq.env.begin-module Name none, log.coq.env.begin-section Name, mk-factory-sort-deps GR CSL, log.coq.env.end-section-name Name, log.coq.env.end-module-name Name _, std.forall CSL (x\ sigma CS\ x = pr _ CS, log.coq.CS.declare-instance CS) ]. func declare-factory-sort-factory gref ->. declare-factory-sort-factory GR :- std.do! [ if-verbose (coq.say {header} "required instances on factory sort for" GR), Name is "SortInstances" ^ {std.any->string {new_int}}, log.coq.env.begin-module Name none, log.coq.env.begin-section Name, mk-factory-sort-factory GR CFL CSL, log.coq.env.end-section-name Name, log.coq.env.end-module-name Name _, std.forall {std.append CFL CSL} (x\ sigma CS\ x = pr _ CS, log.coq.CS.declare-instance CS) ]. pred context.declare i:factories, o:mixins, o:list term, o:term, o:list prop, o:list constant. func mk-factory-sort-deps gref -> list (pair id constant). mk-factory-sort-deps AliasGR CSL :- std.do! [ std.assert-ok! (factory-alias->gref AliasGR GR) "HB: mk-factory-sort-deps", gref->deps GR MLwPRaw, context.declare MLwPRaw MLwP SortParams SortKey SortMSL _, SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GR FSort, log.coq.env.add-section-variable-noimplicits "f" FSort CF, GCF = global (const CF), factory-sort (coercion GRFSort _ GR _), SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GRFSort KSort, coq.mk-app KSort [GCF] KFSortEta, list-w-params_list MLwP ML, std.length ML NMLArgs, coq.mk-n-holes NMLArgs SortMLHoles, std.append {std.append SortParams [SortKey|SortMLHoles]} [GCF] KFSortArgs, coq.mk-app (global GRFSort) KFSortArgs KFSort, std.assert-ok! (coq.unify-eq KFSortEta KFSort) "HB: KRSort not an app", std.map SortMSL (c\ o\ sigma m t\ c = mixin-src _ m t, o = mixin-src KFSort m t) KFSortMSL, KFSortMSL => synthesis.under-mixin-src-from-factory.do! KFSort GCF [declare-all KFSort {findall-classes-for ML} CSL] ]. func mk-factory-sort-factory gref -> list (pair id constant), list (pair id constant). mk-factory-sort-factory AliasGR CFL CSL :- std.do! [ std.assert-ok! (factory-alias->gref AliasGR GR) "HB", gref->deps GR MLwPRaw, context.declare MLwPRaw MLwP SortParams SortKey SortMSL _, SortMSL => synthesis.infer-all-gref->deps SortParams SortKey GR FSort, log.coq.env.add-section-variable-noimplicits "f" FSort CF, std.length {list-w-params_list MLwP} NMLArgs, coq.mk-n-holes NMLArgs SortMLHoles, GCF = global (const CF), coq.mk-app (global GR) {std.append SortParams [GCF|SortMLHoles]} FGCF, declare-const "_" GCF (arity FGCF) CFL CSL ]. % create instances for all possible combinations of types and structure compatible func saturate-instances cs-pattern -> . saturate-instances Filter :- std.do! [ findall-has-mixin-instance Filter ClausesHas, std.map ClausesHas has-mixin-instance_key KL, undup-cs-patterns KL UKL, std.map UKL cs-pattern->term TL, findall-classes AllClasses, std.map ClausesHas has-mixin-instance->mixin-src Clauses, Clauses => std.map2 TL UKL (t\k\CI\sigma Classes\ std.filter AllClasses (no-instance-for k) Classes, declare-all-on-type-constructor t Classes CI) CIL, private.clauses-for-export {std.flatten CIL} ClausesExport, acc-clauses current ClausesExport, ]. func no-instance-for cs-pattern, hbclass ->. no-instance-for K (class _ S _) :- get-structure-sort-projection S (global Proj), coq.CS.db-for Proj K []. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. func declare-instance factoryname, term, term -> list prop, list (pair id constant), list (pair id constant). declare-instance Factory T F Clauses CFL CSL :- current-mode (builder-from T TheFactory FGR _), !, if (get-option "local" tt) (coq.error "HB: declare-instance: cannot make builders local. If you want temporary instances, make an alias, e.g. with let T' := T") true, !, declare-canonical-instances-from-factory-and-local-builders Factory T F TheFactory FGR Clauses CFL CSL. declare-instance Factory T F Clauses CFL CSL :- declare-canonical-instances-from-factory Factory T F Clauses1 CFL CSL, clauses-for-export {std.append CFL CSL} Clauses2, std.append Clauses1 Clauses2 Clauses. func clauses-for-export list (pair id constant) -> list prop. clauses-for-export CL ECL :- if (get-option "export" tt) (coq.env.current-library File, std.map CL (x\r\ sigma i c\ x = pr i c, r = instance-to-export File i c) ECL) (ECL = []). % [add-mixin T F _ M Cl] adds a constant being the mixin instance for M on type % T built from factory F func add-mixin term, factoryname, bool, mixinname -> list prop, list (pair id constant). add-mixin T FGR MakeCanon MissingMixin [MixinSrcCl, BuilderDeclCl] CSL :- std.do! [ new_int N, % timestamp synthesis.assert!-infer-mixin T MissingMixin Bo, MixinSrcCl = mixin-src T MixinName (global (const C)), BuilderDeclCl = builder-decl (builder N FGR MixinName (const C)), std.assert-ok! (coq.typecheck Bo Ty) "declare-instances: mixin illtyped", safe-dest-app Ty (global MixinNameAlias) _, std.assert-ok! (factory-alias->gref MixinNameAlias MixinName) "HB", std.assert! (MissingMixin = MixinName) "HB: anomaly: we built the wrong mixin", % If the mixin instance is already a constant there is no need to % alias it. if (Bo = global (const C)) true (Name is {gref->modname FGR 2 "_"} ^"__to__" ^ {gref->modname MixinName 2 "_"}, if-verbose (coq.say {header} "declare mixin instance" Name), log.coq.env.add-const-noimplicits Name Bo Ty @transparent! C), if (MakeCanon = tt, whd (global (const C)) [] (global (indc _)) _) (std.do! [ if-verbose (coq.say {header} "declare canonical mixin instance" C), with-locality (log.coq.CS.declare-instance C), CSL = [pr "_" C] ]) (CSL = []), ]. func add-all-mixins term, factoryname, list mixinname, bool -> list prop, list (pair id constant). add-all-mixins T FGR ML MakeCanon Clauses CSL :- std.do! [ std.map ML (m\ o\ sigma ClL CSL\ add-mixin T FGR MakeCanon m ClL CSL, o = pr ClL CSL) ClLxCSL_L, std.unzip ClLxCSL_L ClLL CSLL, std.flatten ClLL Clauses, std.flatten CSLL CSL ]. % [postulate-arity A Acc T TS] postulates section variables % corresponding to parameters in arity A. TS is T applied % to all section variables (and hd-beta reduced). Acc should % be [] at call site. func postulate-arity arity, list term, term -> term, term. postulate-arity (parameter ID _ S A) Acc T T1 Ty :- std.assert-ok! (coq.typecheck-ty S _) "arity parameter illtyped", if-verbose (coq.say {header} "postulating" ID), if (var S) (coq.fresh-type S) true, log.coq.env.add-section-variable-noimplicits ID S C, Var = global (const C), postulate-arity (A Var) [Var|Acc] T T1 Ty. postulate-arity (arity Ty) ArgsRev X T Ty :- hd-beta X {std.rev ArgsRev} X1 Stack1, unwind X1 Stack1 T. % We find the new mixins that F build, we build them and shedule them % for becoming builders at section closing time. We also declare % all canonical instances these new mixins allow for, so that the user % can access their theory and notations func declare-canonical-instances-from-factory-and-local-builders factoryname, term, term, term, factoryname -> list prop, list (pair id constant), list (pair id constant). declare-canonical-instances-from-factory-and-local-builders Factory T F _TheFactory FGR Clauses CFL CSL :- std.do! [ synthesis.under-new-mixin-src-from-factory.do! T F (NewMixins\ std.do! [ add-all-mixins T FGR NewMixins ff Clauses CFL, ]), list-w-params_list {factory-provides Factory} ML, Clauses => declare-all T {findall-classes-for ML} CSL, ]. % [declare-canonical-instances-from-factory T F] given a factory F % it uses all known builders to declare canonical instances of structures % on T func declare-canonical-instances-from-factory factoryname, term, term -> list prop, list (pair id constant), list (pair id constant). declare-canonical-instances-from-factory Factory T F ClausesHas CFL CSL :- std.do! [ % The order of the following two "under...do!" is crucial, % priority must be given to canonical mixins % as they are the ones which guarantee forgetful inheritance % hence we add these clauses last. synthesis.local-canonical-mixins-of T MLCano, synthesis.under-mixin-src-from-factory.do! T F [ MLCano => std.do! [ list-w-params_list {factory-provides Factory} ML, add-all-mixins T Factory ML tt Clauses CFL, std.map-filter Clauses (mixin-src->has-mixin-instance ) ClausesHas, ClausesHas => declare-all T {findall-classes-for ML} CSL, % declare-all-on-type-constructor doesn't work here ] ], ]. % If you don't mention the factory in a builder, then Coq won't make % a lambda for it at section closing time. func hack-section-discharging term -> term. hack-section-discharging B B :- current-mode no-builder, !. hack-section-discharging B B1 :- current-mode (builder-from _ TheFactory _ _), !, std.assert-ok! (coq.typecheck TheFactory TheFactoryTy) "TheFactory is illtyped (BUG)", B1 = {{ let _ : lp:TheFactoryTy := lp:TheFactory in lp:B }}. hack-section-discharging B B. % unfolds the constant used for the phant abbreviation to avoid storing all % the phantom abstrctions and idfun that were used to trigger inference func optimize-body term -> term. optimize-body (app[global (const C)| Args]) Red :- (phant-abbrev _ (const C) _ ; (rex_match "phant_" {coq.gref->id (const C)})), !, coq.env.const C (some B) _, hd-beta B Args HD Stack, unwind HD Stack Red. optimize-body (let _ _ T x\x) Red :- !, optimize-body T Red. optimize-body X X. func hnf term -> term. hnf X R :- get-option "hnf" tt, !, unwind {whd X []} R. hnf X X. :index (_ _ 1) func optimize-class-body term, int, term -> term, list prop. optimize-class-body T NParams (let _ _ MBo R) R1 Clauses :- std.do! [ declare-mixin-name {hnf MBo} MC CL1, if (T = global (indt _), MC = global (const C), not(coq.env.opaque? C)) (log.coq.strategy.set [C] (level 1000)) true, % opaque stops simpl optimize-class-body T NParams (R MC) R1 CL2, std.append CL1 CL2 Clauses, ]. optimize-class-body _ _ (app L) (app L) []. func declare-mixin-name term -> term, list prop. declare-mixin-name (global _ as T) T [] :- !. declare-mixin-name T (global GR) [] :- mixin-mem T GR, !. declare-mixin-name T T [] :- coq.safe-dest-app T (global GR) _, not (from _ _ GR), not (get-option "hnf" tt), !. declare-mixin-name T (global (const C)) [mixin-mem T (const C)] :- std.do! [ Name is "HB_unnamed_mixin_" ^ {std.any->string {new_int}}, if-verbose (coq.say {header} "Giving name" Name "to mixin instance" {coq.term->string T}), log.coq.env.add-const-noimplicits Name T _ @transparent! C, ]. func check-non-forgetful-inheritance term, gref. check-non-forgetful-inheritance _ _ :- get-option "non_forgetful_inheritance" tt, !. check-non-forgetful-inheritance T Factory :- std.do! [ if (coq.safe-dest-app T (global (const HdSym)) _, structure-key HdSym _ Super) ( coq.warning "HB" "HB.non-forgetful-inheritance" "non forgetful inheritance detected.\n" "You have two solutions:" "1. (Best practice) Reorganize your hierarchy to make" {nice-gref->string Factory} "depend on" { calc ({nice-gref->string Super} ^ ".") } "See the paper \"Competing inheritance paths in" "dependent type theory\" (https://hal.inria.fr/hal-02463336) for more" "explanations" "2. Use the attribute #[non_forgetful_inheritance] to disable this check." "We strongly advise you encapsulate this instance inside a module," "in order to isolate it from the rest of the code, and to be able" "to import it on demand. See the above paper and the file" "https://github.com/math-comp/hierarchy-builder/blob/master/tests/non_forgetful_inheritance.v" "to witness devastating effects." ) true ]. }} math-comp-hierarchy-builder-4d8a939/HB/pack.elpi000066400000000000000000000070001521677141400214350ustar00rootroot00000000000000 /* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace pack { pred main i:term, i:list argument, o:term. main Ty Args Instance :- std.do! [ std.assert! (not(var Ty)) "HB.pack: the structure to pack cannot be unknown, use HB.pack_for", std.assert! (coq.safe-dest-app {unwind {whd Ty []}} (global Structure) Params) "HB.pack: not a structure", std.assert! (class-def (class Class Structure _)) "HB.pack: not a structure", std.assert! (Args = [trm TSkel|FactoriesSkel]) "HB.pack: not enough arguments", get-constructor Class KC, get-constructor Structure KS, std.assert-ok! (d\ (coq.elaborate-ty-skeleton TSkel _ T d, d = ok) ; coq.elaborate-skeleton TSkel _ T d ) "HB.pack: not a well typed key", private.elab-factories FactoriesSkel T Factories, if (var T) (coq.error "HB.pack: you must pass a type or at least one factory") true, if2 (T = app[global (const SortProj)|ProjParams], structure-key SortProj ClassProj _) (AllFactories = [app[global (const ClassProj)|ProjParams] | Factories], Tkey = T) % already existing class on T (def T _ _ Tkey) % we unfold letins if we can, they may hide constants with CS instances (AllFactories = Factories) (AllFactories = Factories, Tkey = T), % it's a factory, won't add anything private.synth-instance Params KC KS T Tkey AllFactories Instance, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { pred synth-instance.aux i:list term, i:gref, i:gref, i:term, i:term, i:list term, i:list prop, o:term. synth-instance.aux Params KC KS T Tkey [Factory|Factories] MLCano Instance :- synthesis.under-new-mixin-src-from-factory.do! Tkey Factory (_\ synth-instance.aux Params KC KS T Tkey Factories MLCano Instance). synth-instance.aux Params KC KS T Tkey [] MLCano Instance :- MLCano => std.do! [ std.assert-ok! (synthesis.infer-all-args-let Params Tkey KC ClassInstance) "HB.pack: cannot infer the instance", std.append Params [T, ClassInstance] InstanceArgs, Instance = app[global KS | InstanceArgs] ]. pred synth-instance i:list term, i:gref, i:gref, i:term, i:term, i:list term, o:term. synth-instance Params KC KS T Tkey Factories Instance :- if (coq.safe-dest-app Tkey (global _) _) (synthesis.local-canonical-mixins-of Tkey MLCano) (MLCano = []), synth-instance.aux Params KC KS T Tkey Factories MLCano Instance. pred elab-factories i:list argument, i:term, o:list term. elab-factories [] _ []. elab-factories [trm FactorySkel|More] T [Factory|Factories] :- std.assert-ok! (coq.elaborate-skeleton FactorySkel FTy MaybeFactory) "HB.pack: illtyped factory", if2 (factory? {unwind {whd FTy []}} (triple _ _ T1)) % a factory (Factory = MaybeFactory) (coq.safe-dest-app {unwind {whd FTy []}} (global GR) _, structure-key SortP ClassP GR) % a structure instance (coq.mk-n-holes {structure-nparams GR} Params, std.append Params [MaybeFactory] ParamsF, coq.mk-app (global (const SortP)) ParamsF T1, coq.mk-app (global (const ClassP)) ParamsF Factory) (coq.error "HB: argument" {coq.term->string MaybeFactory} "is not a factory, it has type:" {coq.term->string FTy}), std.assert-ok! (coq.unify-eq T T1) "HB.pack: factory for the wrong type", elab-factories More T Factories. }} math-comp-hierarchy-builder-4d8a939/HB/status.elpi000066400000000000000000000055351521677141400220550ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace status { pred print-hierarchy. print-hierarchy :- std.do! [ coq.say "--------------------- Hierarchy -----------------------------------", std.findall (class-def CL_) CL, std.forall CL private.pp-class, coq.say "", coq.say "--------------------- Builders -----------------------------------", std.findall (from A_ B_ C_) FL, std.forall FL private.pp-from, std.findall (mixin-src T_ M_ V_) ML, if (ML = []) true ( coq.say "", coq.say "--------------------- Local mixin instances ----------------------", std.forall ML private.pp-mixin-src ), std.findall (builder-decl BD_) BDL, if (BDL = []) true ( coq.say "", coq.say "--------------------- Builder declarations ----------------------", std.forall BDL private.pp-builder-decl ), std.findall (current-mode BF_) BFL, if (BFL = []) true ( coq.say "", coq.say "--------------------- Current mode ----------------------", std.forall BFL private.pp-current-mode ), ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { pred pp-from i:prop. pp-from (from F M T) :- coq.say "From" {coq.term->string (global F)} "to" {coq.term->string (global M)}, coq.say " " {coq.term->string (global T)}, coq.say "". pred pp-list-w-params i:mixins, i:term. pred pp-list-w-params.list-triple i:list (w-args mixinname), i:term. pred pp-list-w-params.triple i:w-args mixinname. pp-list-w-params (w-params.cons N Ty LwP) T :- @pi-parameter N Ty p\ pp-list-w-params (LwP p) {coq.mk-app T [p]}. pp-list-w-params (w-params.nil N TTy LwP) T :- @pi-parameter N TTy t\ pp-list-w-params.list-triple (LwP t) {coq.mk-app T [t]}. pp-list-w-params.list-triple L S :- coq.say {coq.term->string S} ":=", std.forall L pp-list-w-params.triple. pp-list-w-params.triple (triple M Params T) :- coq.say " " {coq.term->string (app [global M|{std.append Params [T]}])}. pred pp-class i:prop. pp-class (class-def (class _ S MLwP)) :- pp-list-w-params MLwP (global S). pred pp-mixin-src i:prop. pp-mixin-src (mixin-src T M C) :- coq.say {coq.term->string T} "is a" {nice-gref->string M} "thanks to" {coq.term->string C}. pred pp-builder-decl i:prop. pp-builder-decl (builder-decl (builder N F M GR)) :- coq.say "builder" GR "with serial number" N "will build mixin" M "from factory" F. pred pp-current-mode i:prop. pp-current-mode (current-mode (builder-from TheType TheFactory GRF Mod)) :- coq.say "The current key is" TheType "with factory" TheFactory "corresponding to Global Ref" GRF "in module" Mod. }} math-comp-hierarchy-builder-4d8a939/HB/structure.elpi000066400000000000000000000671201521677141400225700ustar00rootroot00000000000000/* Hierarchy Builder: algebraic hierarchies made easy This software is released under the terms of the MIT license */ namespace structure { % HB.structure Definition S P1 P2 := { T of F1 P1 T & F2 P1 (P2*P2) T } % cons p1\ cons p2\ nil t\ [triple f1 [p1] t,triple f2 [p1, {{p1 * p2}}] t] pred declare i:string, i:term, i:sort. declare Module BSkel Sort :- std.do! [ disable-id-phant BSkel BSkelNoId, std.assert-ok! (coq.elaborate-skeleton BSkelNoId _ BNoId) "illtyped structure definition", re-enable-id-phant BNoId B, private.sigT->list-w-params B GRFSwP ClosureCheck, factories-provide GRFSwP PMLwP, list-w-params.flatten-map GRFSwP gref->deps RMLwP, % TODO: extract code from factories-provide list-w-params.append PMLwP RMLwP UnsortedMLwP, w-params.map UnsortedMLwP (p\t\ toposort-mixins) MLwP, list-w-params_list PMLwP PML, list-w-params_list MLwP ML, synthesis.list-w-params.check-key MLwP, if (ClosureCheck = tt, not({std.length PML} = {std.length ML})) (coq.warning "HB" "HB.implicit-structure-dependency" "pulling in dependencies:" {std.map {std.list-diff ML PML} nice-gref->string} "\nPlease list them or end the declaration with '&'") true, private.if-class-already-exists-error Module {findall-classes-for ML} ML, private.if-coverage-not-good-error ML, % TODO: check we never define the superclass of an exising class if-verbose (coq.say {header} "start module" Module), log.coq.env.begin-module Module none, private.declare-class+structure MLwP Sort ClassName Structure SortProjection ClassProjection Factories StructKeyClause, w-params.map MLwP (_\_\_\ mk-nil) NilwP, ClassAlias = (factory-alias->gref ClassName ClassName ok), CurrentClass = (class ClassName Structure MLwP), ClassName = indt ClassInd, coq.env.indt ClassInd _ _ _ _ [ClassK] _, GRDepsClauses = [gref->deps (indt ClassInd) NilwP, gref->deps (indc ClassK) MLwP], std.map ML (m\ o\ o = mixin-class m ClassName) MixinMems, std.filter ML (m\ not (mixin->first-class m _)) NewMixins, std.map NewMixins (m\ r\ r = mixin->first-class m ClassName) MixinFirstClass, if-verbose (coq.say {header} "structure: new mixins" NewMixins), if-verbose (coq.say {header} "structure: mixin first class" MixinFirstClass), if-verbose (coq.say {header} "declaring clone abbreviation"), w-params.then MLwP phant.fun-real phant.fun-real (private.clone-phant-body ClassName SortProjection Structure) PhClone, phant.add-abbreviation "clone" PhClone _ _, if-verbose (coq.say {header} "declaring pack_ constant"), (ClassAlias => class-def CurrentClass => GRDepsClauses => MixinMems => w-params.then MLwP mk-fun mk-fun (private.pack-body ClassName) Pack), if-verbose (coq.say {header} "declaring pack_ constant =" Pack), log.coq.env.add-const-noimplicits "pack_" Pack _ @transparent! ConstPack, GRPack = const ConstPack, if-arg-sort ( if-verbose (coq.say {header} "define arg_sort"), std.assert-ok! (coq.typecheck SortProjection SortProjTy) "HB: BUG: cannot retype projection", log.coq.env.add-const-noimplicits "arg_sort" SortProjection SortProjTy ff ArgSortCst ), if-verbose (coq.say {header} "start module Exports"), log.coq.env.begin-module "Exports" none, %(ClassAlias => class-def CurrentClass => % GRDepsClauses => MixinFirstClass => gref->deps GRPack MLwP => % phant.of-gref tt GRPack [] PhRepack), %if-verbose (coq.say {header} "declaring pack abbreviation =" PhRepack), % phant.add-abbreviation "pack" PhRepack _ PackAbbrev, if (get-option "short.type" ShortType) ( if-verbose (coq.say {header} "short name for type:" ShortType), (@global! => log.coq.notation.add-abbreviation ShortType 0 (global Structure) ff _)) true, coq.mk-app (global Structure) {coq.mk-n-holes {w-params.nparams MLwP}} HB_Instance, if (get-option "short.pack" ShortPack) (std.do! [ if-verbose (coq.say {header} "declaring pack abbreviation:" ShortPack), % coq.notation.abbreviation-body PackAbbrev NPackAbbrev PackAbbrevTrm, % @global! => log.coq.notation.add-abbreviation % ShortPack NPackAbbrev PackAbbrevTrm ff _ coq.notation.add-abbreviation-for-tactic ShortPack "HB.pack_for" [trm HB_Instance] ]) true, % (std.do! [ % PackAbbrevName is Module ^ ".pack", % if-verbose (coq.say {header} "declaring pack abbreviation:" PackAbbrevName), % coq.notation.add-abbreviation-for-tactic PackAbbrevName "HB.pack_for" [trm HB_Instance], %]), if-verbose (coq.say {header} "making coercion from type to target"), synthesis.infer-coercion-tgt MLwP CoeClass, if-arg-sort (private.declare-sort-coercion CoeClass Structure (global (const ArgSortCst))), private.declare-sort-coercion CoeClass Structure SortProjection, if-verbose (coq.say {header} "exporting unification hints"), ClassAlias => Factories => GRDepsClauses => private.declare-unification-hints SortProjection ClassProjection CurrentClass NewJoins, % Register in Elpi's DB the new structure % NOT TODO: All these acc are correctly locaed in an Export Module if (ClassName = indt ClassInd) (std.do![ if-verbose (coq.say {header} "exporting coercions from class to mixins"), std.forall {coq.env.projections ClassInd} (private.export-mixin-coercion ClassName) ]) (coq.say "declare:" ClassName "should be an inductive", fail), if-verbose (coq.say {header} "accumulating various props"), std.flatten [ Factories, [is-structure Structure], NewJoins, [class-def CurrentClass], GRDepsClauses, [gref->deps GRPack MLwP], MixinMems, [StructKeyClause] ] NewClauses, acc-clauses current NewClauses, if-verbose (coq.say {header} "stop module Exports"), log.coq.env.end-module-name "Exports" Exports, log.coq.env.import-module "Exports" Exports, if-verbose (coq.say {header} "declaring on_ abbreviation"), private.mk-infer-key CoeClass ClassProjection NilwP (global Structure) PhClass, phant.add-abbreviation "on_" PhClass _ ClassOfAbbrev, (pi c\ coq.notation.abbreviation ClassOfAbbrev [c] (ClassOfAbbrev_ c)), if-verbose (coq.say {header} "declaring `copy` abbreviation"), coq.mk-app (global ClassName) {params->holes NilwP} AppClassHoles, @global! => log.coq.notation.add-abbreviation "copy" 2 {{fun T C => (lp:(ClassOfAbbrev_ C) : (lp:AppClassHoles T)) }} tt _, if-verbose (coq.say {header} "declaring on abbreviation"), @global! => log.coq.notation.add-abbreviation "on" 1 {{fun T => (lp:{{ ClassOfAbbrev_ {{_}} }} : (lp:AppClassHoles T)) }} tt _OnAbbrev, log.coq.env.end-module-name Module ModulePath, if-verbose (coq.say {header} "end modules; export" Exports), export.module {calc (Module ^ ".Exports")} Exports, if-verbose (coq.say {header} "exporting operations"), ClassAlias => Factories => GRDepsClauses => private.export-operations Structure SortProjection ClassProjection MLwP [] EX MLToExport, % TODO: issue an Arguments op T : rename, where T is the name written by % the user in Definition foo := { T of ... } if-verbose (coq.say {header} "operations meta-data module: ElpiOperations"), ElpiOperationModName is {calc (Module ^ "ElpiOperations")}, log.coq.env.begin-module ElpiOperationModName none, acc-clauses current {std.append EX MixinFirstClass}, log.coq.env.end-module-name ElpiOperationModName ElpiOperations, export.module ElpiOperationModName ElpiOperations, if-verbose (coq.say {header} "abbreviation factory-by-classname"), ClassAlias => NewClauses => factory.declare-abbrev Module (factory.by-classname ClassName) ClassAbbrev, export.clause (phant-abbrev ClassName ClassName ClassAbbrev), NewClauses => if-MC-compat (private.mc-compat-structure Module ModulePath MLToExport {w-params.nparams MLwP} ClassProjection GRPack), % Automatic saturation disabled since it is expensive % NewClauses => instance.saturate-instances, ]. /* ------------------------------------------------------------------------- */ /* ----------------------------- private code ------------------------------ */ /* ------------------------------------------------------------------------- */ namespace private { shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }. % const Po : forall p1 .. pm T m1 .. mn, Extra (Eg Extra = forall x y, x + y = y + z) % const C : forall p1 .. pm s, Extra % Po P1 .. PM T M1 .. MN PoArgs -> C P1 .. PM S PoArgs pred clean-op-ty i:list prop, i:term, i:term, o:term. clean-op-ty [] _ T1 T2 :- copy T1 T2. clean-op-ty [exported-op _ Po C|Ops] S T1 T2 :- gref->deps (const Po) MLwP, w-params.nparams MLwP NParams, std.length {list-w-params_list MLwP} NMixins, (pi L L1 L2 Params Rest PoArgs\ copy (app [global (const Po)| L]) (app [global (const C) | L2]) :- !, std.split-at NParams L Params [_|Rest], std.drop NMixins Rest PoArgs, std.append Params [S|PoArgs] L1, std.map L1 copy L2) => clean-op-ty Ops S T1 T2. pred operation-body-and-ty i:list prop, i:constant, i:structure, i:term, i:term, i:list term, i:term, i:w-args A, o:pair term term. operation-body-and-ty EXI Poperation Struct Psort Pclass Params _T (triple _ ParamsOp _) (pr Bo Ty) :- std.do! [ mk-app (global Struct) Params StructType, mk-app Psort Params PsortP, mk-app Pclass Params PclassP, Bo = fun `s` StructType Body, Ty = prod `s` StructType BodyTy, (@pi-decl `s` StructType s\ sigma Carrier Class\ std.do! [ mk-app PsortP [s] Carrier, mk-app PclassP [s] Class, synthesis.under-mixin-src-from-factory.do! Carrier Class [ % just in case.. synthesis.infer-all-gref->deps ParamsOp Carrier (const Poperation) (Body s), std.assert-ok! (coq.typecheck (Body s) (DirtyTy s)) "export-1-operation: Body illtyped", clean-op-ty EXI s (DirtyTy s) (BodyTy s), ], ]), ]. % given an operation (a mixin projection) we generate a constant projection the % same operation out of the package structure (out of the class field of the % structure). We also provide all the other mixin dependencies (other misins) % of the package structure. pred export-1-operation i:mixinname, i:structure, i:term, i:term, i:one-w-params mixinname, i:option constant, i:list prop, o:list prop. export-1-operation _ _ _ _ _ none EX EX :- !. % not a projection, no operation export-1-operation M Struct Psort Pclass MwP (some Poperation) EXI EXO :- !, std.do! [ coq.gref->id (const Poperation) Name, w-params.then MwP mk-fun-prod ignore (operation-body-and-ty EXI Poperation Struct Psort Pclass) (pr Body BodyTy), if-verbose (coq.say {header} "export operation" Name), log.coq.env.add-const-noimplicits Name Body BodyTy @transparent! C, w-params.nparams MwP NP, NImplicits is NP + 1, std.iota NImplicits INI, std.map INI (_\r\ r = maximal) Implicits, @global! => log.coq.arguments.set-implicit (const C) [Implicits], EXO = [exported-op M Poperation C|EXI] ]. % Given a list of mixins, it exports all operations in there pred export-operations.aux i:structure, i:term, i:term, i:one-w-params mixinname, i:list prop, o:list prop. export-operations.aux Struct ProjSort ProjClass MwP EX1 EX2 :- !, std.do! [ w-params_1 MwP (indt M), coq.env.projections M Poperations, std.fold Poperations EX1 (export-1-operation (indt M) Struct ProjSort ProjClass MwP) EX2, ]. pred mixin-not-already-declared i:one-w-params mixinname. mixin-not-already-declared MwP :- w-params_1 MwP M, not(mixin->first-class M _), M = indt _. pred export-operations i:structure, i:term, i:term, i:mixins, i:list prop, o:list prop, o:list mixinname. export-operations Structure ProjSort ProjClass MLwP EX1 EX2 MLToExport :- std.do! [ distribute-w-params MLwP LMwP, std.filter LMwP mixin-not-already-declared LMwPToExport, std.fold LMwPToExport EX1 (export-operations.aux Structure ProjSort ProjClass) EX2, std.map LMwPToExport w-params_1 MLToExport, ]. pred mk-coe-class-body i:factoryname, % From class i:factoryname, % To class i:mixins, % To mixins i:list term, i:term, % Params, T i:list (w-args mixinname), o:term. mk-coe-class-body FC TC TMLwP Params T _ CoeBody :- std.do! [ mk-app (global FC) {std.append Params [T]} Class, list-w-params_list TMLwP TML, std.map TML (from FC) Builders, std.map Builders (x\r\mk-app (global x) Params r) BuildersP, factory->nparams TC TCNP, mk-app (global {get-constructor TC}) {coq.mk-n-holes TCNP} KCHoles, (pi c\ sigma Mixes\ std.map BuildersP (builder\r\ r = app[builder, T, c]) Mixes, mk-app KCHoles [T | Mixes] (ClassCoercion c)), CoeBody = {{ fun (c : lp:Class) => lp:(ClassCoercion c) }} ]. pred mk-coe-structure-body i:structure, % From structure i:structure, % To structure i:factoryname, % To factory (for nparams) i:term, % class coercion i:term, % sort projection i:term, % class projection i:list term, i:term, % Params, T i:list (w-args mixinname), o:term. mk-coe-structure-body StructureF StructureT TC Coercion SortProjection ClassProjection Params _T _ SCoeBody :- std.do! [ mk-app (global StructureF) Params StructureP, mk-app SortProjection Params SortP, mk-app ClassProjection Params ClassP, mk-app Coercion Params CoercionP, factory->nparams TC TCNP, mk-app (global {get-constructor StructureT}) {coq.mk-n-holes TCNP} PackPH, SCoeBody = {{ fun s : lp:StructureP => (* let T := lp:SortP s in*) lp:PackPH (lp:SortP s) (lp:CoercionP (lp:SortP s) (lp:ClassP s)) }}, ]. % [declare-coercion P1 P2 C1 C2] declares a structure and a class coercion % from C1 to C2 given P1 P2 the two projections from the structure of C1 pred declare-coercion i:term, i:term, i:hbclass, i:hbclass. declare-coercion SortProjection ClassProjection (class FC StructureF FMLwP) (class TC StructureT TMLwP) :- std.do! [ gref->modname StructureF 2 "_" ModNameF, gref->modname StructureT 2 "_" ModNameT, CName is ModNameF ^ "_class__to__" ^ ModNameT ^ "_class", SName is ModNameF ^ "__to__" ^ ModNameT, if-verbose (coq.say {header} "declare coercion" SName), w-params.then FMLwP mk-fun mk-fun (mk-coe-class-body FC TC TMLwP) CoeBody, ErrorMessage is "The structures " ^ ModNameF ^ " and " ^ ModNameT ^ " are incompatible: the coercion between them cannot be synthesized", std.assert-ok! (coq.elaborate-skeleton CoeBody Ty CoeBody') ErrorMessage, if-verbose (coq.say {header} "declare coercion hint" CName), log.coq.env.add-const-noimplicits CName CoeBody' Ty @transparent! C, log.coq.coercion.declare (coercion (const C) 1 FC (grefclass TC)), Coercion = global (const C), w-params.then FMLwP mk-fun ignore (mk-coe-structure-body StructureF StructureT TC Coercion SortProjection ClassProjection) SCoeBody, ErrorMessage is "The structures " ^ ModNameF ^ " and " ^ ModNameT ^ " are incompatible: the coercion between them cannot be synthesized", std.assert-ok! (coq.elaborate-skeleton SCoeBody STy SCoeBody') ErrorMessage, if-verbose (coq.say {header} "declare unification hint" SName), log.coq.env.add-const-noimplicits SName SCoeBody' STy @transparent! SC, log.coq.coercion.declare (coercion (const SC) 0 StructureF (grefclass StructureT)), log.coq.CS.declare-instance SC, w-params.nparams FMLwP NparamsSC, acc-clause current (sub-class FC TC SC NparamsSC) ]. pred join-body i:int, i:int, i:structure, i:term, i:term, i:term, i:term, i:term, i:list term, i:name, i:term, i:(term -> A), o:term. join-body N1 N2 S3 S2_Pack S1_sort S3_to_S1 S2_class S3_to_S2 P N _Ty _F (fun N S3P Pack) :- !, mk-app (global S3) P S3P, !, @pi-decl N S3P s\ sigma S3_to_S1_Ps S3_to_S2_Ps S1_sortS3Ps S2_classS3Ps Holes1 Holes2 \ std.do! [ coq.mk-n-holes N2 Holes2, coq.mk-n-holes N1 Holes1, mk-app S3_to_S1 {std.append P [s]} S3_to_S1_Ps, mk-app S1_sort {std.append Holes1 [S3_to_S1_Ps]} S1_sortS3Ps, mk-app S3_to_S2 {std.append P [s]} S3_to_S2_Ps, mk-app S2_class {std.append Holes2 [S3_to_S2_Ps]} S2_classS3Ps , mk-app S2_Pack {std.append Holes2 [S1_sortS3Ps, S2_classS3Ps]} (Pack s) ]. pred declare-join i:hbclass, i:pair hbclass hbclass, o:prop. declare-join (class C3 S3 MLwP3) (pr (class C1 S1 _) (class C2 S2 _)) (join C1 C2 C3) :- Name is "join_" ^ {gref->modname S3 2 "_"} ^ "_between_" ^ {gref->modname S1 2 "_"} ^ "_and_" ^ {gref->modname S2 2 "_"}, get-structure-coercion S3 S2 S3_to_S2, get-structure-coercion S3 S1 S3_to_S1, get-structure-sort-projection S1 S1_sort, get-structure-class-projection S2 S2_class, get-constructor S2 S2_Pack, factory->nparams C1 N1, factory->nparams C2 N2, if-verbose (coq.say {header} "declare unification hint" Name), w-params.fold MLwP3 mk-fun (join-body N1 N2 S3 (global S2_Pack) S1_sort S3_to_S1 S2_class S3_to_S2) JoinBody, std.assert-ok! (coq.typecheck JoinBody Ty) "declare-join: JoinBody illtyped", log.coq.env.add-const-noimplicits Name JoinBody Ty @transparent! J, log.coq.CS.declare-instance J. % TODO: this works under the invariant: we never have two classes that % contain exactly the same mixins. HB.structure should enforce this % and eventually just alias the existing one rather than failing. % TODO: HB.structure should check we are not inserting the class % in the middle of existing ones. Possible fix: always declare all intermediate % possibilities but without proper names (requires the previous TODO about % aliasing already existing stuff). pred declare-unification-hints i:term, i:term, i:hbclass, o:list prop. declare-unification-hints SortProj ClassProj CurrentClass NewJoins :- std.do! [ findall-classes All, std.filter All (sub-class? CurrentClass) AllSuper, std.forall AllSuper (declare-coercion SortProj ClassProj CurrentClass), findall-newjoins CurrentClass AllSuper TodoJoins, std.map TodoJoins (declare-join CurrentClass) NewJoins ]. % For each mixin we declare a field and apply the mixin to its dependencies % (that are previously declared fields recorded via field-for-mixin) pred synthesize-fields i:term, i:list (w-args mixinname), o:record-decl. synthesize-fields _T [] end-record. synthesize-fields T [triple M Args _|ML] (field _ Name MTy Fields) :- std.do! [ Name is {gref->modname M 2 "_"} ^ "_mixin", if-verbose (coq.say {header} "typing class field" M), std.assert! (synthesis.infer-all-gref->deps Args T M MTy) "anomaly: a field type cannot be solved", @pi-decl `m` MTy m\ mixin-src T M m => synthesize-fields T ML (Fields m) ]. pred synthesize-fields.body i:list term, i:term, i:list (w-args mixinname), o:indt-decl. synthesize-fields.body _Params T ML (record "axioms_" {{ Type }} "Class" FS) :- synthesize-fields T ML FS. pred mk-record+sort-field i:sort, i:name, i:term, i:(term -> record-decl), o:indt-decl. mk-record+sort-field Sort _ T F (record "type" (sort Sort) "Pack" (field _ "sort" T F)). pred mk-class-field i:classname, i:list term, i:term, i:list (w-args mixinname), o:record-decl. mk-class-field ClassName Params T _ (field [canonical ff] "class" (app [global ClassName|Args]) _\end-record) :- std.append Params [T] Args. % Builds the axioms record and the factories from this class to each mixin pred declare-class+structure i:mixins, i:sort, o:factoryname, o:structure, o:term, o:term, o:list prop, o:prop. declare-class+structure MLwP Sort (indt ClassInd) (indt StructureInd) SortProjection ClassProjection AllFactories (structure-key SortP ClassP (indt StructureInd)):- std.do! [ if-verbose (coq.say {header} "declare axioms record"MLwP ), % TODO: enhance elpi-typechecker to deduce the type of `mk-parameter explicit` from the argmuments % passed to w-params.then w-params.then MLwP (mk-parameter explicit : (pred i:name, i:term, i:(term -> indt-decl), o:indt-decl)) (mk-parameter explicit) synthesize-fields.body ClassDeclaration, std.assert-ok! (coq.typecheck-indt-decl ClassDeclaration) "declare-class: illtyped", (@primitive! => log.coq.env.add-indt ClassDeclaration ClassInd), coq.env.projections ClassInd Projs, % TODO: put this code in a named clause w-params.nparams MLwP NParams, std.map2 {list-w-params_list MLwP} Projs (m\ p\ r\ sigma P\ std.assert! (p = some P) "BUG: we build a class with an anonymous field", r = from (indt ClassInd) m (const P)) Factories, AllFactories = [factory->nparams (indt ClassInd) NParams | Factories], if-verbose (coq.say {header} "declare type record"), w-params.then MLwP (mk-parameter explicit : (pred i:name, i:term, i:(term -> indt-decl), o:indt-decl)) (mk-record+sort-field Sort) (mk-class-field (indt ClassInd)) StructureDeclaration, std.assert-ok! (coq.typecheck-indt-decl StructureDeclaration) "declare: illtyped", if (get-option "primitive" tt) (@primitive! => log.coq.env.add-indt StructureDeclaration StructureInd) (log.coq.env.add-indt StructureDeclaration StructureInd), coq.env.projections StructureInd [some SortP, some ClassP], global (const SortP) = SortProjection, global (const ClassP) = ClassProjection, ]. % Declares "sort" as a Coercion Proj : Structurename >-> CoeClass. pred declare-sort-coercion i:class, i:structure, i:term. declare-sort-coercion CoeClass StructureName (global Proj) :- if-verbose (coq.say {header} "declare sort coercion"), log.coq.coercion.declare (coercion Proj 0 StructureName CoeClass). pred if-class-already-exists-error i:id, i:list hbclass, i:list mixinname. if-class-already-exists-error _ [] _. if-class-already-exists-error N [class _ S ML1wP|CS] ML2 :- list-w-params_list ML1wP ML1, if (std.list-eq-set ML1 ML2) (coq.error "Structure" {nice-gref->string S} "contains the same mixins as" N) (if-class-already-exists-error N CS ML2). pred export-mixin-coercion i:classname, i:option constant. export-mixin-coercion _ none. export-mixin-coercion ClassName (some C) :- coq.env.typeof (const C) CTy, coq.prod-tgt->gref CTy MixinGR, if-verbose (coq.say {header} "export class to mixin coercion for mixin" {nice-gref->string MixinGR}), log.coq.coercion.declare (coercion (const C) _ ClassName (grefclass MixinGR)). pred mc-compat-structure i:string, i:modpath, i:list mixinname, i:int, i:term, i:gref, i:option gref. mc-compat-structure ModuleName _Module NewMixins CNParams ClassProjection GRPack Axioms :- std.do! [ CompatModuleName is "MathCompCompat" ^ ModuleName, log.coq.env.begin-module CompatModuleName none, % to avoid collisions log.coq.env.begin-module ModuleName none, if (Axioms = some GR) (@global! => log.coq.notation.add-abbreviation "axiom" 0 (global GR) ff _) true, if (NewMixins = [NewMixin]) (std.do! [ if-verbose (coq.say "mc-compat-structure: declaring notations 'axioms', 'mixin_of' and 'Mixin'"), factory->nparams NewMixin NewMixinNP, MArgs is NewMixinNP + 1, mk-eta MArgs {coq.env.typeof NewMixin} (global NewMixin) EtaNewMixin, @global! => log.coq.notation.add-abbreviation "axioms" MArgs EtaNewMixin ff _, @deprecated! "mathcomp 2.0.0" "use the factory instead" => @global! => log.coq.notation.add-abbreviation "mixin_of" MArgs EtaNewMixin ff _, std.assert! (factory->constructor NewMixin FK) "BUG: Factory constructor missing", std.assert! (phant-abbrev FK _ PhAbb) "BUG: missing phant-abbrev", @deprecated! "mathcomp 2.0.0" "use the F.Build instead" => @global! => log.coq.notation.add-abbreviation "Mixin" 0 {coq.notation.abbreviation PhAbb {coq.mk-n-holes MArgs}} ff _, if-verbose (coq.say "mc-compat-structure: declaring pack abbreviation"), @deprecated! "mathcomp 2.0.0" "use native HB Structure.pack instead" => phant.add-abbreviation "mcpack" {phant.of-gref ff GRPack [NewMixin]} _ _, ]) (if-verbose (coq.say "mc-compat-structure: not exactly one new mixin")), if-verbose (coq.say "mc-compat-structure: declaring notation 'class_of'"), std.assert-ok! (coq.typecheck ClassProjection ClassProjectionTy) "wtf", CArgs is CNParams + 1, mk-eta CArgs ClassProjectionTy ClassProjection EtaClassProjection, @global! => log.coq.notation.add-abbreviation "class_of" CArgs EtaClassProjection ff _, log.coq.env.end-module-name ModuleName _, log.coq.env.end-module-name CompatModuleName MCCompat, log.coq.env.export-module CompatModuleName MCCompat, %coq.env.import-module Module, ]. pred clone-phant-body i:factoryname, i:term, i:structure, i:list term, i:term, i:list (w-args mixinname), o:phant-term. clone-phant-body ClassName SortProjection ((indt I) as Structure) PL T _ PhF :- std.do! [ std.assert! (coq.env.indt I _ _ _ _ [PackC] _) "wtf", mk-app (global (indc PackC)) {std.append PL [T]} PackPLT, mk-app (global Structure) PL SPL, (@pi-decl `cT` SPL cT\ mk-app (global ClassName) {std.append PL [T]} CPL, @pi-decl `c` CPL c\ (Ph cT c) = {phant.fun-unify none T {mk-app {mk-app SortProjection PL} [cT]} {phant.fun-unify none cT {mk-app PackPLT [c]} {phant.init {mk-app PackPLT [c]}} }}), PhF = {phant.fun-real `cT` SPL cT\ {phant.fun-implicit `c` CPL c\ Ph cT c }} ]. % [pack-body ClassName P T MLwA B] asserts % B = fun m0 ... mn => Pack P T (Class P T m0 ... mn) % under a context with P and T pred pack-body i:classname, i:list term, i:term, i:list (w-args mixinname), o:term. pack-body ClassName PL T MLwA F :- std.do! [ class-def (class ClassName S _), get-constructor ClassName BuildC, get-constructor S PackS, synthesis.under-mixins.then MLwA mk-fun (pack-body.aux PL T BuildC PackS) F, ]. pack-body.aux PL T BuildC PackS Body :- !, std.do! [ synthesis.infer-all-gref->deps PL T BuildC Class, mk-app (global PackS) {std.append PL [T, Class]} Body ]. pred mk-infer-key i:class, i:term, i:mixins, i:term, o:phant-term. mk-infer-key CoeClass K (w-params.nil ID _ _) St PhK :- @pi-parameter ID St t\ phant.init {mk-app K [t]} (PhKBo t), phant.fun-infer-type CoeClass {coq.id->name ID} St PhKBo PhK. mk-infer-key CoeClass K (w-params.cons ID Ty W) St R :- @pi-parameter ID Ty t\ mk-infer-key CoeClass {mk-app K [t]} (W t) {mk-app St [t]} (PhT t), phant.fun-implicit {coq.id->name ID} Ty PhT R. pred if-coverage-not-good-error i:list mixinname. if-coverage-not-good-error ML :- coq.gref.list->set ML MS, std.forall ML (if-coverage-not-good-error.one MS). pred if-coverage-not-good-error.one i:coq.gref.set, i:mixinname. if-coverage-not-good-error.one MS M :- mixin->first-class M C, !, class-coverage [C] CMS, if (coq.gref.set.subset CMS MS) true (coq.gref.set.elements {coq.gref.set.remove M CMS} MissinFromCurrent, coq.error "HB: the first structure declared in this hierarchy containing" {nice-gref->string M} "is" {nice-gref->string C} "which also contains" {std.map MissinFromCurrent nice-gref->string} "." "\nThe are two ways to fix this problem:" "1) change the current structure to contain" {std.map MissinFromCurrent nice-gref->string} "as well;" "2) amend the hierarchy by declaring a structure before" {nice-gref->string C} "which contains at most" {std.map {coq.gref.set.elements {coq.gref.set.inter CMS MS}} nice-gref->string}). if-coverage-not-good-error.one _ _. % new class is the first covering M pred product->triples i:term, o:list (w-args factoryname), o:bool. product->triples {{ lib:hb.prod lp:A lp:B }} L ClosureCheck :- !, product->triples B GRB ClosureCheck, product->triples A GRA _, std.append GRA GRB L. product->triples {{ True }} [] tt :- !. product->triples {{ False }} [] ff :- !. product->triples A [GR] tt :- std.assert! (factory? A GR) "A structure can only mention known factories". pred sigT->list-w-params i:term, o:list-w-params factoryname, o:bool. sigT->list-w-params (fun N T B) L C :- coq.name->id N ID, % TODO: we should read the ID from the definition type which is an arity containing ids L = w-params.cons ID T Rest, @pi-decl N T p\ sigT->list-w-params (B p) (Rest p) C. sigT->list-w-params {{ lib:@hb.sigT _ lp:{{ fun N Ty B }} }} L C :- coq.name->id N ID, % TODO: we should read the ID from the definition type which is an arity containing ids L = w-params.nil ID Ty Rest, @pi-decl N Ty t\ product->triples (B t) (Rest t) C. }} math-comp-hierarchy-builder-4d8a939/HB/structures.v000066400000000000000000001314471521677141400222730ustar00rootroot00000000000000(* Support constants, to be kept in sync with shim/structures.v *) From Corelib Require Import ssreflect ssrfun. Add Search Blacklist "Builders_". Add Search Blacklist "__canonical__". Add Search Blacklist "__to__". Add Search Blacklist "_between_". Add Search Blacklist "_mixin". Variant error_msg := NoMsg | IsNotCanonicallyA (x : Type). Definition unify T1 T2 (t1 : T1) (t2 : T2) (s : error_msg) := phantom T1 t1 -> phantom T2 t2. Definition id_phant {T} {t : T} (x : phantom T t) := x. Definition id_phant_disabled {T T'} {t : T} {t' : T'} (x : phantom T t) := Phantom T' t'. Definition nomsg : error_msg := NoMsg. Definition is_not_canonically_a x := IsNotCanonicallyA x. Definition new {T} (x : T) := x. Definition eta {T} (x : T) := x. Definition ignore {T} (x: T) := x. Definition ignore_disabled {T T'} (x : T) (x' : T') := x'. (* ********************* structures ****************************** *) From elpi Require Import elpi. Register unify as hb.unify. Register id_phant as hb.id. Register id_phant_disabled as hb.id_disabled. Register ignore as hb.ignore. Register ignore_disabled as hb.ignore_disabled. Register Corelib.Init.Datatypes.None as hb.none. Register nomsg as hb.nomsg. Register is_not_canonically_a as hb.not_a_msg. Register Corelib.Init.Datatypes.Some as hb.some. Register Corelib.Init.Datatypes.pair as hb.pair. Register Corelib.Init.Datatypes.prod as hb.prod. Register Corelib.Init.Specif.sigT as hb.sigT. Register Corelib.ssr.ssreflect.phant as hb.phant. Register Corelib.ssr.ssreflect.Phant as hb.Phant. Register Corelib.ssr.ssreflect.phantom as hb.phantom. Register Corelib.ssr.ssreflect.Phantom as hb.Phantom. Register Corelib.Init.Logic.eq as hb.eq. Register Corelib.Init.Logic.eq_refl as hb.erefl. Register new as hb.new. Register eta as hb.eta. #[deprecated(since="HB 1.0.1", note="use #[key=...] instead")] Notation indexed T := T (only parsing). Declare Scope HB_scope. Notation "{ A 'of' P & .. & Q }" := (sigT (fun A => (prod P .. (prod Q True) ..)%type)) (at level 0, A at level 99) : HB_scope. Notation "{ A 'of' P & .. & Q & }" := (sigT (fun A => (prod P .. (prod Q False) ..)%type)) (at level 0, A at level 99) : HB_scope. Global Open Scope HB_scope. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This data represents the hierarchy and some other piece of state to implement the commands of this file *) #[interp] Elpi Db hb.db lp:{{ typeabbrev mixinname gref. typeabbrev classname gref. typeabbrev factoryname gref. typeabbrev structure gref. typeabbrev (w-args A) (triple A (list term) term). kind w-params type -> type. type w-params.cons id -> term -> (term -> w-params A) -> w-params A. type w-params.nil id -> term -> (term -> A) -> w-params A. typeabbrev (list-w-params A) (w-params (list (w-args A))). typeabbrev (one-w-params A) (w-params (w-args A)). typeabbrev mixins (list-w-params mixinname). typeabbrev factories (list-w-params mixinname). typeabbrev (w-mixins A) (pair mixins (w-params A)). %%%%% Classes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % (class C S ML) represents a class C packed in S containing mixins ML. % Example: % % HB.mixin Record IsZmodule V := { ... } % HB.mixin Record Zmodule_IsLmodule (R : ringType) V of Zmodule V := { ... } % HB.structure Definition Lmodule R := {M of Zmodule M & Zmodule_IsLmodule R M} % % The class description for Lmodule would be: % % class (indt «Lmodule.axioms») /* The record with all mixins */ % (indt «Lmodule.type») /* The record with sort and class */ % (w-params.cons "R" {{ Ring.type }} P \ /* The first parameter, named "R" */ % w-params.nil "M" {{ Type }} T \ /* The key of the structure */ % [..., /* deps of IsZmodule.mixin */ % triple (indt «IsZmodule.mixin») [] T, /* a mixins with its params */ % triple (indt «Zmodule_IsLmodule.mixin») [P] T ]) /* another mixins */ % % If some mixin parameters depend on other mixins (through a canonical instance that % can be inferred from them). Since our structure does not account for dependencies % between mixins (the list in the end is flat), we compensate by replacing canonical % instances by calls to `S.Pack T {{lib:elpi.hole}}`, and extending the reconstruction % mecanism of mixins to also reinfer these holes. kind hbclass type. type class classname -> structure -> mixins -> hbclass. % class-def contains all the classes ever declared pred class-def o:hbclass. %%%%% Builders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [from FN MN F] invariant: % "F : forall p1 .. pn T LMN, FN p1 .. pn T LMN1 -> MN c1 .. cm T LMN2" where % - LMN1 and LMN2 are sub lists of LMN % - c1 .. cm are terms built using p1 .. pn and T % - [factory-requires FN LMN] % [from _ M _] tests whether M is a declared mixin. pred from o:factoryname, o:mixinname, o:gref. %%%%% Abbreviations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [phant-abbrev Cst AbbrevCst Abbrev] % Stores phantom abbreviation Abbrev associated with Cst % AbbrevCst is the constant that serves as support % e.g. Definition AbbrevCst := fun t1 t2 (phant_id t1 t2) => Cst t2. % Notation Abbrev t1 := (AbbrevCst t1 _ idfun). pred phant-abbrev o:gref, o:gref, o:abbreviation. % [factory-alias->gref X GR] when X is already a factory X = GR % however, when X is a phantom abbreviated gref, we find the underlying % factory gref GR associated to it. func factory-alias->gref gref -> gref, diagnostic. factory-alias->gref PhGR GR ok :- phant-abbrev GR PhGR _, !. factory-alias->gref GR GR ok :- phant-abbrev GR _ _, !. factory-alias->gref GR _ (error Msg) :- !, Msg is {coq.term->string (global GR)} ^ " is not a factory or its library (" ^ { std.string.concat "." {std.drop-last 1 {coq.gref->path GR} } } ^ ") was not correctly imported". %%%%% Cache of known facts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [factory->constructor F K] means K is a constructor for % the factory F. :index(2) func factory->constructor factoryname -> gref. % [factory->nparams F N] says that F has N parameters :index(2) func factory->nparams factoryname -> int. % [is-structure GR] tests if GR is a known structure pred is-structure o:gref. % [is-factory GR] tests if GR is a known factory pred is-factory o:gref. % [sub-class C1 C2 Coercion12 NparamsCoercion] C1 is a sub-class of C2, % see also sub-class? which computes it on the fly :index (2 2 1) pred sub-class o:classname, o:classname, o:constant, o:int. % [gref->deps GR MLwP] is a (pre computed) list of dependencies of a know global % constant. The list is topologically sorted :index(2) func gref->deps gref -> mixins. % [join C1 C2 C3] means that C3 inherits from both C1 and C2 pred join o:classname, o:classname, o:classname. % Section local memory of names for mixins, so that we can reuse them % and build terms with simpler conversion problems (less unfolding % in order to discover two mixins are the same) % @gares : is it really a func. Ideally I think so, bu we load mixin-mem via % `Clauses =>` in infer-class. Should perform a dynamic check? func mixin-mem term -> gref. %%%%%% Memory of exported mixins (HB.structure) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Operations (named mixin fields) need to be exported exactly once, % but the same mixin can be used in many structure, hence this memory % to keep the invariant. % Also we remember which is the first class/structure that includes % a given mixin, assuming the invariant that this first class is also % the minimal class that includes this mixin. % [mixin->first-class M C] states that C is the first/minimal class % that contains the mixin M :index(2) func mixin->first-class mixinname -> classname. % memory of exported operations (TODO: document fiels) pred exported-op o:mixinname, o:constant, o:constant. % memory of factory sort coercion pred factory-sort o:coercion. % memory of canonical projections for a structure (X.sort, X.class, X.type) pred structure-key o:constant, o:constant, o:structure. %%%%%% Membership of mixins to a class %%%%%%%%%%%%%%%% % [mixin-class M C] means M belongs to C pred mixin-class o:mixinname, o:classname. %% database for HB.context %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [mixin-src T M X] states that X can be used to reconstruct % an instance of the mixin [M T …], directly or through a builder. % Since HB.builders sections can declare canonical instances of % mixins that do not yet form a structure, we cannot resort to % Coq's CS database (which is just for structures). pred mixin-src o:term, o:mixinname, o:term. % [has-mixin-instance K M G] states that G is a reference to an instance % of mixin M for subject K pred has-mixin-instance o:cs-pattern, o:mixinname, o:gref. %% database for HB.builders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [builder N TheFactory TheMixin S] is used to % remember that the user run [HB.instance S] hence [HB.end] has to % synthesize builders from TheFactory to TheMixin mixins generated by S. % N is a timestamp. kind builder type. type builder int -> factoryname -> mixinname -> gref -> builder. pred builder-decl o:builder. %% database for builder-local canonical instances %%%%%%%%%%%%%%%%%%%%%%% pred local-canonical o:constant. % To tell HB.end what we are doing kind declaration type. % TheType, TheFactory and it's name and the name of the module encloding all that type builder-from term -> term -> factoryname -> id -> declaration. type no-builder declaration. pred current-mode o:declaration. %% database for HB.export / HB.reexport %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % library, nice-name, object pred module-to-export o:string, o:id, o:modpath. pred instance-to-export o:string, o:id, o:constant. pred abbrev-to-export o:string, o:id, o:gref. pred clause-to-export o:string, o:prop. %% database for HB.locate and HB.about %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% pred decl-location o:gref, o:loc. % [docstring Loc Doc] links a location in the source text and some doc pred docstring o:loc, o:string. }}. (* This database is used by the parsing phase only *) #[synterp] Elpi Db export.db lp:{{ pred module-to-export o:string, o:modpath. }}. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This is like Locate but tells you the file and line at which the constant or inductive was generated. *) #[arguments(raw)] Elpi Command HB.locate. Elpi Accumulate Db hb.db. (* Since it can become rather large, accumulating the DB is often by far the most expensive accumulation. It is then worth sharing its cache between the commands. To this end, we accumulate the DB first in each command to ensure the same dependencies and maximize cache hits. For instance, this can save a few (2 or 3) percents of total compilation time on MathComp. *) Elpi Accumulate lp:{{ :name "start" main [str S] :- !, if (decl-location {coq.locate S} Loc) (coq.say "HB: synthesized in file" Loc) (coq.say "HB" S "not synthesized by HB"). main _ :- coq.error "Usage: HB.locate .". }}. Elpi Typecheck. Elpi Export HB.locate. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This is like About but understands HB generated stuff, namely - structures, eg Foo.type - classes, eg Foo - factories, eg Bar - factory constructors, eg Bar.Build - canonical projections, eg Foo.sort - canonical value, eg Z, prod, ... *) #[arguments(raw)] Elpi Command HB.about. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/about.elpi". Elpi Accumulate lp:{{ :name "start" main [str S] :- !, with-attributes (with-logging (about.main S)). main _ :- coq.error "Usage: HB.about .". }}. Elpi Typecheck. Elpi Export HB.about. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.howto (T) Foo.type d] prints possible sequences of factories to equip a type [T] with a structure [Foo.type], taking into account structures already instantiated on [T]. The search depth [d] is the maximum length of the sequences, 3 by default. The first argument [T] is optional, when ommited [Foo.type] is built from scratch. Finally, the first argument can be another structure [Bar.type], in which case [Foo.type] is built starting from [Bar.type]. *) #[arguments(raw)] Elpi Command HB.howto. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/about.elpi". Elpi Accumulate File "HB/howto.elpi". Elpi Accumulate lp:{{ :name "start" main [trm T, str STgt] :- !, with-attributes (with-logging (howto.main-trm T STgt none)). main [trm T, str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-trm T STgt (some Depth))). main [str T, str STgt] :- !, with-attributes (with-logging (howto.main-str T STgt none)). main [str T, str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-str T STgt (some Depth))). main [str STgt] :- !, with-attributes (with-logging (howto.main-from [] STgt none)). main [str STgt, int Depth] :- !, with-attributes (with-logging (howto.main-from [] STgt (some Depth))). main _ :- coq.error "Usage: HB.howto [()|] [].". }}. Elpi Typecheck. Elpi Export HB.howto. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This command prints the status of the hierarchy (Debug) *) #[arguments(raw)] Elpi Command HB.status. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/status.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- !, status.print-hierarchy. main _ :- coq.error "Usage: HB.status.". }}. Elpi Typecheck. Elpi Export HB.status. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** This command prints the hierarchy to a dot file. You can use [[ tred file.dot | xdot - ]] to visualize file.dot *) #[arguments(raw)] Elpi Command HB.graph. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/graph.elpi". Elpi Accumulate lp:{{ :name "start" main [str File] :- with-attributes (with-logging (graph.to-file File)). main _ :- coq.error "Usage: HB.graph .". }}. Elpi Typecheck. Elpi Export HB.graph. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.mixin] declares a mixin Syntax to create a mixin [MixinName] with requirements [Factory1] .. [FactoryN]: [[ HB.mixin Record MixinName T & Factory1 T & … & FactoryN T := { op : T -> … … property : forall x : T, op … … } ]] Synthesizes: - [MixinName T] abbreviation for the type of the (degenerate) factory - [MixinName.Build T] abbreviation for the constructor of the factory Note: [T & f1 T & … & fN T] is syntactic sugar for [T (_ : f1 T) … (_ : fN T)] Supported attributes: - [#[primitive]] experimental attribute to make the mixin/factory primitive, - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.mixin. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [A] :- with-attributes (with-logging (factory.declare-mixin A)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, export-module }. pred actions i:id. actions N :- begin-module N none, begin-section N, end-section, begin-module "Exports" none, end-module E, end-module _, export-module E, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)). main [indt-decl D] :- record-decl->id D N, with-attributes (actions N). main _ :- coq.error "Usage: HB.mixin Record T & F A & … := { … }.". }}. Elpi Typecheck. Elpi Export HB.mixin. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.pack] and [HB.pack_for] are tactic-in-term synthesizing a structure instance. In the middle of a term, in a context expecting a [Structure.type], you can write [HB.pack T F] to use factory [F] to equip type [T] with [Structure]. If [T] is already a rich type, eg [T : OtherStructure.type] or if [T] is a global constant with canonical structure instances attached to it, then this piece of info is used to infer a [Structure]. If the context does not impose a [Structure.type] typing constraint, then you can use [HB.pack_for Structure.type T F]. You can pass zero or more factories like [F] but they must all typecheck in the current context (the type is not enriched progressively). Structure instances are projected to their class in order to obtain a factory. Examples: [[ pose Fa : IsSomething T := IsSomething.Build T ... pose A : A.type := HB.pack T Fa. pose Fb : IsMore A := IsMore.Build ... pose B := HB.pack_for B.type T A Fb. ]] If [Structure.type] as parameters [P1..Pn] then you should use [HB.pack T F1..Fn] or [HB.pack_for (Structure.type P1..Pn) T F1..Fn] *) Elpi Tactic HB.pack_for. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/pack.elpi". Elpi Accumulate lp:{{ :name "start" solve (goal _ _ S _ [trm Ty | Args] as G) GLS :- with-attributes (with-logging (std.do! [ pack.main Ty Args InstanceSkel, std.assert-ok! (coq.elaborate-skeleton InstanceSkel S Instance) "HB.pack_for: the instance does not solve the goal", log.refine.no_check Instance G GLS, ])). }}. Elpi Typecheck. Elpi Export HB.pack_for. Elpi Tactic HB.pack. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/pack.elpi". Elpi Accumulate lp:{{ :name "start" solve (goal _ _ Ty _ Args as G) GLS :- with-attributes (with-logging (std.do! [ pack.main Ty Args InstanceSkel, std.assert-ok! (coq.elaborate-skeleton InstanceSkel Ty Instance) "HB.pack: the instance does not solve the goal", log.refine.no_check Instance G GLS, ])). }}. Elpi Typecheck. Elpi Export HB.pack. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.structure] declares a packed structure. Syntax to declare a structure combing the axioms from [Factory1] … [FactoryN]. The second syntax has a trailing [&] to pull in factory requirements silently. [[ HB.structure Definition StructureName params := { A of Factory1 … A & … & FactoryN … A }. HB.structure Definition StructureName params := { A of Factory1 … A & … & FactoryN … A & }. ]] Synthesizes: - [StructureName A] the type of the class that regroups all the factories [Factory1 … A] … [FactoryN … A]. - [StructureName.type params] the structure type that packs together [A] and its class. - [StructureName.sort params] the first projection of the previous structure, - [StructureName.clone params T cT] a legacy repackaging function that eta expands the canonical [StructureName.type] of [T], using [cT] if provided. - [StructureName.class sT : StructureName sT] projects out the class of [sT : StructureName.type params], - [StructureName.copy T T' : StructureName T] returns the class of the canonical [StructureName.type] of [T], and gives it the type [Structure T]. It is thus ready to use in combination with HB.instance, as in [[ (* Cloning a structure from another one, given by the user *) HB.instance Definition _ := StructureName.copy T cT. ]] - [StructureName.on T : StructureName T] infers the class of the canonical [StructureName.type] of [T]. This is a shortcut for [StructureName.Copy T T], and it will succeeds if a reduction of [T] is canonically a [StructureName.type]. Disclaimer: any function other that the ones described above, including pattern matching (using Gallina [match], [let] or tactics ([case], [elim], etc)) is an internal and must not be relied upon. Also hand-crafted [Canonical] declarations of such structures will break the hierarchy. Use [HB.instance] instead. Supported attributes: - [#[mathcomp]] attempts to generate a backward compatibility layer with mathcomp: trying to infer the right [StructureName.pack], - [#[arg_sort]] defines an alias [StructureName.arg_sort] for [StructureName.sort], and declares it as the main coercion. [StructureName.sort] is still declared as a coercion but the only reason is to make sure Coq does not print it. Cf ##[fingroup.v]##. - [#[short(type="shortName")]] produces the abbreviation [shortName] for [Structure.type] - [#[short(pack="shortName")]] produces the abbreviation [shortName] for [HB.pack_for Structure.type] - [#[primitive]] experimental attribute to make the structure a primitive record, - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.structure. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate File "HB/structure.elpi". Elpi Accumulate lp:{{ :name "start" main [const-decl N (some B) Arity] :- std.do! [ % compute the universe for the structure (default ) prod-last {coq.arity->term Arity} Ty, if (ground_term Ty) (Sort = Ty) (Sort = {{Type}}), sort Univ = Sort, with-attributes (with-logging (structure.declare N B Univ)), ]. }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, import-module, export-module }. pred actions i:id. actions N :- begin-module N none, begin-module "Exports" none, end-module E, import-module E, end-module _, export-module E, begin-module {calc (N ^ "ElpiOperations")} none, end-module O, export-module O, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)), coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File O)), if (get-option "mathcomp" tt ; get-option "mathcomp.axiom" _) (actions-compat N) true. pred actions-compat i:id. actions-compat ModuleName :- CompatModuleName is "MathCompCompat" ^ ModuleName, begin-module CompatModuleName none, begin-module ModuleName none, end-module _, end-module O, export-module O, % is this a bug? % coq.env.current-library File, % coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File O)). true. main [const-decl N _ _] :- !, with-attributes (actions N). main _ :- coq.error "Usage: HB.structure Definition := { A of A & … & A }". }}. Elpi Typecheck. Elpi Export HB.structure. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* [HB.saturate [key]] saturates all instances (of all known keys, if key is not given) w.r.t. the current hierarchy. When two (unrelated) files are imported it might be that the instances declared in one file are sufficient to instantiate structures declared in the other file. This command reconsiders all types with a canonical structure instance and see if the they are also equipped with new ones. *) #[arguments(raw)] Elpi Command HB.saturate. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ main [] :- !, with-attributes (with-logging (instance.saturate-instances _)). main [str "Type"] :- !, with-attributes (with-logging (instance.saturate-instances (cs-sort _))). main [str K] :- !, coq.locate K GR, with-attributes (with-logging (instance.saturate-instances (cs-gref GR))). main [trm T] :- !, term->cs-pattern T P, with-attributes (with-logging (instance.saturate-instances P)). main _ :- coq.error "Usage: HB.saturate [key]". }}. Elpi Typecheck. Elpi Export HB.saturate. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.instance] associates to a type all the structures that can be obtained from the provided factory inhabitant. Syntax for declaring a canonical instance: [[ HB.instance Definition N Params := Factory.Build Params T … ]] Supported attributes: - [#[export]] to flag the instance so that it is redeclared by [#[HB.reexport]] - [#[local]] to indicate that the instance should not survive the section. - [#[non_forgetful_inheritance]] allows non forgetful inheritance, i.e. inheritance via an instance declaration rather than via dependencies. See tests/non_forgetful_inheritance.v and "Competing inheritance paths in dependent type theory" (https://hal.inria.fr/hal-02463336) - [#[verbose]] for a verbose output. - [#[hnf] to compute the head normal form of CS instances before declaring them *) #[arguments(raw)] Elpi Command HB.instance. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate lp:{{ :name "start" main [const-decl Name (some BodySkel) TyWPSkel] :- !, with-attributes (with-logging (instance.declare-const Name BodySkel TyWPSkel _ _)). main [T0, F0] :- !, coq.warning "HB" "HB.deprecated" "The syntax \"HB.instance Key FactoryInstance\" is deprecated, use \"HB.instance Definition\" instead", with-attributes (with-logging (instance.declare-existing T0 F0)). }}. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-section, end-section }. main [const-decl _ _ (arity _)] :- !. main [const-decl _ _ (parameter _ _ _ _)] :- !, SectionName is "hb_instance_" ^ {std.any->string {new_int} }, begin-section SectionName, end-section. main [_, _] :- !. main _ :- coq.error "Usage: HB.instance Definition := T ...". }}. Elpi Typecheck. Elpi Export HB.instance. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.factory] declares a factory. It has the same syntax of [HB.mixin] *) #[arguments(raw)] Elpi Command HB.factory. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [A] :- with-attributes (with-logging (factory.declare A)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section, end-section, export-module }. pred actions i:id. actions N :- begin-module N none, begin-section N, end-section, begin-module "Exports" none, end-module E, end-module _, export-module E, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File E)). main [indt-decl D] :- record-decl->id D N, with-attributes (actions N). main [const-decl N _ _] :- with-attributes (actions N). main _ :- coq.error "Usage: HB.factory Record T & F A & … := { … }.\nUsage: HB.factory Definition T of F A := t.". }}. Elpi Typecheck. Elpi Export HB.factory. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.builders] starts a section to declare the builders associated to a factory. [HB.end] ends that section. Syntax to declare builders for factory [Factory]: [[ HB.builders Context A (f : Factory A). … HB.instance A someFactoryInstance. … HB.end. ]] [HB.builders] starts a section (inside a module of unspecified name) where: - [A] is a type variable - all the requirements of [Factory] were postulated as variables - [f] is variable of type [Factory A] - all classes whose requirements can be obtained from [Factory] are declared canonical on [A] - for each operation [op] and property [prop] (named fields) of [Factory A] a [Notation] named [op] and [property] for the partial application of [op] and [property] to the variable [f] The former [op] and [property] are aliased [Super.op] and [Super.property] [HB.end] ends the section and closes the module and synthesizes - for each structure inhabited via [HB.instance] it defined all builders to known mixins Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.builders. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate File "HB/builders.elpi". Elpi Accumulate lp:{{ :name "start" main [ctx-decl C] :- with-attributes (with-logging (builders.begin C)). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-module, end-module, begin-section }. pred actions i:id. actions N :- begin-module N none, begin-module "Super" none, end-module _, begin-section N. main [ctx-decl _] :- !, with-attributes (actions {calc ("Builders_" ^ {std.any->string {new_int} })}). main _ :- coq.error "Usage: HB.builders Context A (f : F1 A).". }}. Elpi Typecheck. Elpi Export HB.builders. #[arguments(raw)] Elpi Command HB.end. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/builders.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- with-attributes (with-logging builders.end). }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ end-module, end-section, begin-module, end-module, export-module }. pred actions. actions :- end-section, begin-module {calc ("Builders_Export_" ^ {std.any->string {new_int} })} none, end-module M, end-module _, export-module M, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File M)). main [] :- !, with-attributes actions. main _ :- coq.error "Usage: HB.end.". }}. Elpi Typecheck. Elpi Export HB.end. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.export Modname] does the work of [Export Modname] but also schedules [Modname] to be exported later on, when [HB.reexport] is called. [HB.export Constname] does nothing, but schedules [Constname] to be made available via a Notation at HB.reexport time. Note that the list of things to be exported is stored in the current module, hence the recommended way to do is [[ Module Algebra. HB.mixin .... HB.structure ... Module MoreExports. ... End MoreExports. HB.export MoreExports. ... HB.builders ... Lemma aux_fact : .... HB.export aux_fact. ... HB.end. ... Module Export. HB.reexport. End Exports. End Algebra. Export Algebra.Exports. ]] Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.export. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate lp:{{ :name "start" main [str M] :- !, with-attributes (with-logging (export.any M)). main _ :- coq.error "Usage: HB.export M.". }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ export-module }. pred actions i:list located. actions [loc-modpath MP] :- !, export-module MP, coq.env.current-library File, coq.elpi.accumulate current "export.db" (clause _ _ (module-to-export File MP)). actions []. main [str M] :- !, with-attributes (actions {coq.locate-all M}). main _ :- coq.error "Usage: HB.export M.". }}. Elpi Typecheck. Elpi Export HB.export. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.reexport] Exports all modules, canonical instances and constants that were previously exported via [HB.export]. It is useful to create one big module with all exports at the end of a file. It optionally takes the name of a module or a component of the current module path (a module which is not closed yet) *) #[arguments(raw)] Elpi Command HB.reexport. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate lp:{{ :name "start" main [] :- !, with-attributes (with-logging (export.reexport-all-modules-and-CS none)). main [str M] :- !, with-attributes (with-logging (export.reexport-all-modules-and-CS (some M))). main _ :- coq.error "Usage: HB.reexport.". }}. #[synterp] Elpi Accumulate File "HB/common/utils-synterp.elpi". #[synterp] Elpi Accumulate Db export.db. #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ export-module }. pred module-in-module i:list string, i:prop. module-in-module PM (module-to-export _ M) :- coq.modpath->path M PC, std.appendR PM _ PC. % sublist pred actions i:option id. actions Filter :- coq.env.current-library File, compute-filter Filter MFilter, std.findall (module-to-export File Module_) ModsCL, std.filter {list-uniq ModsCL} (module-in-module MFilter) ModsCLFiltered, std.forall ModsCLFiltered (x\sigma mp\x = module-to-export _ mp, export-module mp). main [] :- !, with-attributes (actions none). main [str M] :- !, with-attributes (actions (some M)). main _ :- coq.error "Usage: HB.reexport.". }}. Elpi Typecheck. Elpi Export HB.reexport. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) From elpi.apps Require Import locker. Elpi Export mlock As HB.lock. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* Inactive command: [HB.declare] This command populates the current section with canonical instances. Syntax: [[ HB.declare Context (p1 : P1) ... (pn : Pn) (t : T) & F0 & ... & Fk. ]] Effect: [[ Variables (p1 : P1) ... (pn : Pn) (t : T). Variable m0 : M0 ... T. HB.instance Definition _ : M0 ... T := m0. .. Variable mk : Ml ... T. HB.instance Definition _ : Ml ... T := ml. ]] where: - factories F0 .. Fk produce mixins M0 .. Ml. Supported attributes: - [#[verbose]] for a verbose output. *) #[arguments(raw)] Elpi Command HB.declare. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate File "HB/common/synthesis.elpi". Elpi Accumulate File "HB/common/phant-abbreviation.elpi". Elpi Accumulate File "HB/export.elpi". Elpi Accumulate File "HB/instance.elpi". Elpi Accumulate File "HB/context.elpi". Elpi Accumulate File "HB/factory.elpi". Elpi Accumulate lp:{{ :name "start" main [Ctx] :- Ctx = ctx-decl _, !, with-attributes (with-logging ( factory.argument->w-mixins Ctx (pr FLwP _), context.declare FLwP _ _ _ _ _)). main _ :- coq.error "Usage: HB.declare Context ". }}. Elpi Typecheck. Elpi Export HB.declare. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** [HB.check T] acts like [Check T] but supports the attribute [#[skip="rex"]] that skips the action on Coq version matches rex. It also understands the [#[fail]] attribute. *) #[arguments(raw)] Elpi Command HB.check. Elpi Accumulate Db hb.db. Elpi Accumulate File "HB/common/stdpp.elpi". Elpi Accumulate File "HB/common/database.elpi". Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". Elpi Accumulate File "HB/common/utils.elpi". Elpi Accumulate File "HB/common/log.elpi". Elpi Accumulate lp:{{ :name "start" main [trm Skel] :- !, with-attributes (with-logging (check-or-not Skel)). main _ :- coq.error "usage: HB.check (term).". pred check-or-not i:term. check-or-not Skel :- coq.version VersionString _ _ _, if (get-option "skip" R, rex_match R VersionString) (coq.warning "HB" "HB.skip" {get-option "elpi.loc"} "Skipping test on Coq" VersionString "as requested") (log.coq.check Skel Ty T Result, if (Result = error Msg) (if (get-option "fail" tt) (coq.say "The command did fail as expected with message:" Msg) (coq.error "HB.check:" Msg)) (if (get-option "fail" tt) (coq.error "The command did not fail") (coq.say "HB.check:" {coq.term->string T} ":" {coq.term->string Ty}))). }}. Elpi Typecheck. Elpi Export HB.check. (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (** Technical notations from /Canonical Structures for the working Coq user/ *) Notation "`Error_cannot_unify: t1 'with' t2" := (unify t1 t2 None) (at level 0, format "`Error_cannot_unify: t1 'with' t2", only printing) : form_scope. Notation "`Error: t `is_not_canonically_a T" := (unify t _ (Some (is_not_canonically_a, T))) (at level 0, T at level 0, format "`Error: t `is_not_canonically_a T", only printing) : form_scope. math-comp-hierarchy-builder-4d8a939/LICENSE000066400000000000000000000017771521677141400203770ustar00rootroot00000000000000Permission 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. math-comp-hierarchy-builder-4d8a939/Makefile000066400000000000000000000137661521677141400210330ustar00rootroot00000000000000# -*- Makefile -*- ###################################################################### # USAGE: # # # # make all: Build the MathComp library entirely, # # make test-suite: Run the test suite, # # make only TGTS="...vo": Build the selected libraries of MathComp. # # # # The rules this-config::, this-build::, this-only::, # # this-test-suite::, this-distclean::, this-clean:: # # and __always__:: may be extended. # # # # Additionally, the following variables may be customized: # SUBDIRS?= COQBIN?=$(dir $(shell command -v coqtop || command -v rocq)) COQTOP=$(shell command -v coqtop || echo "$(COQBIN)rocq repl") COQMAKEFILE?=$(shell command -v coq_makefile || echo "$(COQBIN)rocq makefile") COQDEP?=$(COQBIN)coqdep COQPROJECT?=_CoqProject COQMAKEOPTIONS?= COQMAKEFILEOPTIONS?= V?= VERBOSE?=V TGTS?= ###################################################################### # local context: ----------------------------------------------------- .PHONY: all config build only test-suite test-suite-stdlib clean distclean __always__ .SUFFIXES: H:= $(if $(VERBOSE),,@) # not used yet TOP = $(dir $(lastword $(MAKEFILE_LIST))) COQMAKE = $(MAKE) -f Makefile.coq $(COQMAKEOPTIONS) COQMAKE_TESTSUITE = $(MAKE) -f Makefile.test-suite.coq $(COQMAKEOPTIONS) COQMAKE_TESTSUITE_STDLIB = $(MAKE) -f Makefile.test-suite-stdlib.coq $(COQMAKEOPTIONS) BRANCH_coq:= $(shell $(COQTOP) -v | head -1 | grep -E '(trunk|master)' \ | wc -l | sed 's/ *//g') # coq version: ifneq "$(BRANCH_coq)" "0" COQVVV:= dev else COQVVV:=$(shell $(COQTOP) --print-version | cut -d" " -f1) endif COQV:= $(shell echo $(COQVVV) | cut -d"." -f1) COQVV:= $(shell echo $(COQVVV) | cut -d"." -f1-2) # export to sub- targets export COQBIN export COQMAKEFILE export COQV export COQVV export COQVVV # all: --------------------------------------------------------------- all: $(MAKE) config $(MAKE) build $(MAKE) test-suite # Makefile.coq: ------------------------------------------------------ Makefile.coq: $(COQPROJECT) Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT) -o Makefile.coq # Test suite --------------------------------------------------------- Makefile.test-suite.coq: $(COQPROJECT).test-suite Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT).test-suite -o Makefile.test-suite.coq # Test suite Stdlib -------------------------------------------------- Makefile.test-suite-stdlib.coq: $(COQPROJECT).test-suite-stdlib Makefile $(COQMAKEFILE) $(COQMAKEFILEOPTIONS) -f $(COQPROJECT).test-suite-stdlib -o Makefile.test-suite-stdlib.coq # Global config, build, clean and distclean -------------------------- config: sub-config this-config build: sub-build this-build only: sub-only this-only test-suite: sub-test-suite this-test-suite test-suite-stdlib: sub-test-suite-stdlib this-test-suite-stdlib clean: sub-clean this-clean distclean: sub-distclean this-distclean # Local config, build, clean and distclean --------------------------- .PHONY: this-config this-build this-only this-test-suite this-test-suite-stdlib this-distclean this-clean this-config:: __always__ @if $$(command -v coqc >/dev/null) ; then \ if [ -e config.stamp -a "`coqc --print-version`" = "`cat config.stamp 2>/dev/null`" ] ; then \ echo 'already configured';\ else\ coqc --print-version > config.stamp;\ echo 'configuring for ' `coqc --print-version`;\ if (coqc --version | grep -q '8.20') ; then \ echo '*****************************************************************';\ echo 'old coq version detected, double check the diff before committing';\ echo '*****************************************************************';\ sed -i.bak -e 's/From Corelib/From Coq/' `find . -name \*.v` ; \ sed -i.bak -e 's/IntDef/ZArith/' `find . -name \*.v` ; \ fi;\ fi ; fi # Remove all of the above when requiring Rocq >= 9.0 this-build:: this-config Makefile.coq +$(COQMAKE) this-only:: this-config Makefile.coq +$(COQMAKE) only "TGTS=$(TGTS)" this-test-suite:: build Makefile.test-suite.coq +$(COQMAKE_TESTSUITE) this-test-suite-stdlib:: build Makefile.test-suite-stdlib.coq +$(COQMAKE_TESTSUITE_STDLIB) this-distclean:: this-clean rm -f config.stamp rm -f Makefile.coq Makefile.coq.conf rm -f Makefile.test-suite.coq Makefile.test-suite.coq.conf rm -f Makefile.test-suite-stdlib.coq Makefile.test-suite-stdlib.coq.conf this-clean:: __always__ @if [ -f Makefile.coq ]; then $(COQMAKE) cleanall; fi @if [ -f Makefile.test-suite.coq ]; then $(COQMAKE_TESTSUITE) cleanall; fi @if [ -f Makefile.test-suite-stdlib.coq ]; then $(COQMAKE_TESTSUITE_STDLIB) cleanall; fi # Install target ----------------------------------------------------- .PHONY: install install: __always__ Makefile.coq $(COQMAKE) install # counting lines of Coq code ----------------------------------------- .PHONY: count COQFILES = $(shell grep '.v$$' $(COQPROJECT)) count: @coqwc $(COQFILES) | tail -1 | \ awk '{printf ("%d (spec=%d+proof=%d)\n", $$1+$$2, $$1, $$2)}' # Additionally cleaning backup (*~) files ---------------------------- this-distclean:: rm -f $(shell find . -name '*~') # Make in SUBDIRS ---------------------------------------------------- ifdef SUBDIRS sub-%: __always__ @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $(@:sub-%=%); done else sub-%: __always__ @true endif # Make of individual .vo --------------------------------------------- structures.vo : %.vo: __always__ Makefile.coq +$(COQMAKE) $@ $(addsuffix o,$(wildcard examples/*.v examples/*/*.v tests/*.v tests/unit/*.v)): __always__ config build Makefile.test-suite.coq Makefile.test-suite-stdlib.coq +$(COQMAKE_TESTSUITE) $@ +$(COQMAKE_TESTSUITE_stdlib) $@ nix: nix-shell --arg do-nothing true --run "updateNixToolBox && genNixActions" .PHONY: nix math-comp-hierarchy-builder-4d8a939/Makefile.coq.local000066400000000000000000000003771521677141400226770ustar00rootroot00000000000000# Coq does not know about Elpi Accumulate File, so we declare the dependency here HB/structures.vo : $(wildcard HB/*.elpi HB/common/*.elpi) clean:: $(SHOW)'CLEAN *.hb *.hb.old' $(HIDE) find . -name \*.hb -delete $(HIDE) find . -name \*.hb.old -delete math-comp-hierarchy-builder-4d8a939/Makefile.test-suite.coq.local000066400000000000000000000020051521677141400247720ustar00rootroot00000000000000COQ_MINOR=$(shell echo $(COQ_VERSION) | cut -d . -f 2 | cut -d + -f 1) output_for=`\ if [ -e $(1).out.$(COQ_MINOR) ]; then\ echo $(1).out.$(COQ_MINOR);\ else\ echo $(1).out;\ fi` DIFF=\ @if [ -z "$$COQ_ELPI_ATTRIBUTES" ]; then \ echo OUTPUT DIFF $(1);\ $(COQTOP) $(COQFLAGS) $(COQLIBS) -topfile $(1) \ < $(1) 2>&1 \ | sed 's/Coq < *//g' \ | sed 's/Rocq < *//g' \ | grep -v '^$$' \ | grep -v -e "Skipping rcfile" -e "is declared" -e "is defined" -e "Loading ML file" -e "Welcome to Coq" -e "Welcome to Rocq" \ | sed 's/characters \([0-9]\+\)-[0-9]\+/character \1/' \ > $(1).out.aux;\ diff -u --strip-trailing-cr $(call output_for,$(1)) $(1).out.aux;\ fi post-all:: $(call DIFF, tests/err_missin_subject.v) $(call DIFF, tests/compress_coe.v) $(call DIFF, tests/err_miss_key.v) $(call DIFF, tests/missing_join_error.v) $(call DIFF, tests/not_same_key.v) $(call DIFF, tests/hnf.v) $(call DIFF, tests/err_miss_dep.v) $(call DIFF, tests/err_bad_mix.v) $(call DIFF, tests/err_instance_nop.v) math-comp-hierarchy-builder-4d8a939/README.md000066400000000000000000000157511521677141400206460ustar00rootroot00000000000000[![Actions Status](https://github.com/math-comp/hierarchy-builder/workflows/CI/badge.svg)](https://github.com/math-comp/hierarchy-builder/actions) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://coq.zulipchat.com/#narrow/stream/237868-Hierarchy-Buidlder) HB logo ### Hierarchy Builder Hierarchy Builder (HB) provides high level commands to declare a hierarchy of algebraic structure (or interfaces if you prefer the glossary of computer science) for the Coq system. Given a structure one can develop its theory, and that theory becomes automatically applicable to all the examples of the structure. One can also declare alternative interfaces, for convenience or backward compatibility, and provide glue code linking these interfaces to the structures part of the hierarchy. HB commands compile down to Coq modules, sections, records, coercions, canonical structure instances and notations following the *packed classes* discipline which is at the core of the [Mathematical Components](https://github.com/math-comp/math-comp) library. All that complexity is hidden behind a few concepts and a few declarative Coq commands. ## Example ```coq From HB Require Import structures. From Coq Require Import ssreflect ZArith. HB.mixin Record IsAddComoid A := { zero : A; add : A -> A -> A; addrA : forall x y z, add x (add y z) = add (add x y) z; addrC : forall x y, add x y = add y x; add0r : forall x, add zero x = x; }. HB.structure Definition AddComoid := { A of IsAddComoid A }. Notation "0" := zero. Infix "+" := add. Check forall (M : AddComoid.type) (x : M), x + x = 0. ``` This is all we need to do in order to declare the `AddComoid` structure and write statements in its signature. We proceed by declaring how to obtain an Abelian group out of the additive, commutative, monoid. ```coq HB.mixin Record IsAbelianGrp A of IsAddComoid A := { opp : A -> A; addNr : forall x, opp x + x = 0; }. HB.structure Definition AbelianGrp := { A of IsAbelianGrp A & IsAddComoid A }. Notation "- x" := (opp x). ``` Abelian groups feature the operations and properties given by the `IsAbelianGrp` mixin (and its dependency `IsAddComoid`). ```coq Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0. Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed. ``` We proceed by showing that `Z` is an example of both structures, and use the lemma just proved on a statement about `Z`. ```coq HB.instance Definition Z_CoMoid := IsAddComoid.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbGrp := IsAbelianGrp.Build Z Z.opp Z.add_opp_diag_l. Lemma example2 (x : Z) : x + (- x) = - 0. Proof. by rewrite example. Qed. ``` ## Documentation For a tutorial, see the [platform docs](https://github.com/rocq-prover/platform-docs/tree/main/src/hierarchy_builder). This [paper](https://hal.inria.fr/hal-02478907) describes the language in details, and the corresponding talk [is available on youtube](https://www.youtube.com/watch?v=F6iRaTlQrlo). The [wiki](https://github.com/math-comp/hierarchy-builder/wiki) gathers some tricks and FAQs. If you want to work on the implementation of HB, this [recorded hacking session](https://www.youtube.com/watch?v=gmaJjCbzqO0) may be relevant to you. ### Installation & availability
(click to expand)

- You can install HB via OPAM ```shell opam repo add rocq-released https://rocq-prover.org/opam/released opam install rocq-hierarchy-builder ``` - You can use it in nix with the attribute `rocqPackages_9_X.hierarchy-builder` e.g. via `nix-shell -p rocq_9_0 -p rocqPackages_9_0.hierarchy-builder`

### Key concepts
(click to expand)

- a *mixin* is a bare bone building block of the hierarchy, it packs operations and axioms. - a *factory* is a package of operations and properties that is elaborated by HB to one or more mixin. A mixin is hence a trivial factory. - a *structure* is declared by attaching zero or more factories to a type. - a *builder* is a user provided piece of code capable of building one or more mixins from a factory. - an *instance* is an example of a structure: it provides all operation and fulfills all axioms.

### The commands of HB
(click to expand)

- HB core commands: - `HB.mixin` declares a mixin, - `HB.structure` declares a structure, - `HB.factory` declares a factory, - `HB.builders` and `HB.end` declare a set of builders, - `HB.instance` declares a structure instance, - `HB.declare` declares a context with parameters, key and mixins. - `HB.saturate` reconsiders all mixin instances to see if some newly declared structure can be inhabited - HB core tactic-in-term: - `HB.pack` to synthesize a structure instance in the middle of a term. - HB utility commands: - `HB.export` exports a module and schedules it for re-export - `HB.reexport` exports all modules, instances and constants scheduled for re-export - `HB.lock` locks a definition behind an opaque symbol and an unfolding equation using Coq module system - HB queries: - `HB.about` is similar to `About` but prints more info on HB structures, like the known instances and where they are declared - `HB.locate` is similar to `Locate`, prints file name and line of any global constant synthesized by HB - `HB.graph` prints the structure hierarchy to a dot file - `HB.howto` prints sequences of factories to equip a type with a given structure - HB debug commands: - `HB.status` dumps the contents of the hierarchy (debug purposes) - `HB.check` is similar to `Check` (testing purposes) The documentation of all commands can be found in the comments of [structures.v](HB/structures.v), search for `Elpi Command` and you will find them. All commands can be prefixed with the attribute `#[verbose]` to get an idea of what they are doing. For debugging and teaching purposes, passing the attributes `#[log]` or `#[log(raw)]` to a HB command prints Coq commands which are *almost* equivalent to its effect. Hence, copy-pasting the displayed commands into your source file is not expected to work, and we strongly recommend against it.

### Demos
(click to expand)

- [demo1](examples_stdlib/demo1/) and [demo3](examples/demo3/) declare and evolve a hierarchy up to rings with various clients that are tested not to break when the hierarchy evolves - [demo2](examples_stdlib/demo2/) describes the subtle triangular interaction between groups, topological space and uniform spaces. Indeed, 1. all uniform spaces induce a topology, which makes them topological spaces, but 2. all topological groups (groups that are topological spaces such that the addition and opposite are continuous) induce a uniformity, which makes them uniform spaces. We solve this seamingly mutual dependency using HB.

math-comp-hierarchy-builder-4d8a939/_CoqProject000066400000000000000000000003111521677141400215040ustar00rootroot00000000000000HB/structures.v -arg -w -arg -elpi.accumulate-syntax -arg -w -arg +elpi.typecheck -arg -w -arg -elpi.typecheck-syntax -arg -w -arg -elpi.flex-clause -Q HB HB -R tests HB.tests -R examples HB.examples math-comp-hierarchy-builder-4d8a939/_CoqProject.test-suite000066400000000000000000000030711521677141400236170ustar00rootroot00000000000000-arg -w -arg -redundant-canonical-projection -arg -w -arg -projection-no-head-constant -arg -w -arg -abstract-large-number -arg -w -arg -disj-pattern-notation -arg -w -arg -notation-overridden -arg -w -arg +elpi.typecheck examples/readme.v examples/hulk.v examples/demo3/hierarchy_0.v examples/demo3/hierarchy_1.v examples/demo3/hierarchy_2.v examples/demo3/test_0_0.v examples/demo3/test_1_0.v examples/demo3/test_2_0.v examples/demo4/hierarchy_0.v examples/demo5/hierarchy_0.v # examples/cat/cat.v examples/cat/cat.v tests/test_howto.v tests/type_of_exported_ops.v tests/duplicate_structure.v tests/instance_params_no_type.v tests/test_CS_db_filtering.v tests/subtype.v tests/log_impargs_record.v tests/compress_coe.v tests/grefclass.v tests/local_instance.v tests/lock.v tests/interleave_context.v tests/not_same_key.v #tests/factory_sort.v tests/hb_pack.v tests/declare.v tests/short.v tests/instance_before_structure.v tests/primitive_records.v tests/non_forgetful_inheritance.v tests/fix_loop.v tests/test_synthesis_params.v tests/hnf.v tests/fun_instance.v tests/issue284.v tests/issue287.v tests/two_hier.v tests/instance_merge_with_param.v tests/instance_merge_with_distinct_param.v tests/instance_merge.v tests/unit/enrich_type.v tests/unit/mixin_src_has_mixin_instance.v tests/unit/mk_src_map.v tests/unit/close_hole_term.v tests/unit/struct.v tests/factory_when_notation.v tests/saturate_on.v tests/saturate_export.v tests/bug_435.v tests/bug_447.v tests/unimported_relevant_class.v tests/unimported_irrelevant_class.v -R tests HB.tests -R examples HB.examples -Q HB HB math-comp-hierarchy-builder-4d8a939/_CoqProject.test-suite-stdlib000066400000000000000000000026731521677141400251050ustar00rootroot00000000000000-arg -w -arg -redundant-canonical-projection -arg -w -arg -projection-no-head-constant -arg -w -arg -abstract-large-number -arg -w -arg -disj-pattern-notation -arg -w -arg -notation-overridden -arg -w -arg +elpi.typecheck examples_stdlib/demo1/hierarchy_0.v examples_stdlib/demo1/hierarchy_1.v examples_stdlib/demo1/hierarchy_2.v examples_stdlib/demo1/hierarchy_3.v examples_stdlib/demo1/hierarchy_4.v examples_stdlib/demo1/hierarchy_5.v examples_stdlib/demo1/test_0_0.v examples_stdlib/demo1/test_1_0.v examples_stdlib/demo1/test_2_0.v examples_stdlib/demo1/test_3_0.v examples_stdlib/demo1/test_3_3.v examples_stdlib/demo1/test_4_0.v examples_stdlib/demo1/test_4_3.v examples_stdlib/demo1/test_5_0.v examples_stdlib/demo1/test_5_3.v examples_stdlib/demo2/classical.v examples_stdlib/demo2/stage10.v examples_stdlib/demo2/stage11.v examples_stdlib/FSCD2020_material/V1.v examples_stdlib/FSCD2020_material/V2.v examples_stdlib/FSCD2020_material/V3.v examples_stdlib/FSCD2020_material/V4.v examples_stdlib/FSCD2020_talk/V1.v examples_stdlib/FSCD2020_talk/V2.v examples_stdlib/FSCD2020_talk/V3.v examples_stdlib/Coq2020_material/CoqWS_demo.v examples_stdlib/Coq2020_material/CoqWS_abstract.v examples_stdlib/Coq2020_material/CoqWS_expansion/withHB.v examples_stdlib/Coq2020_material/CoqWS_expansion/withoutHB.v tests_stdlib/exports.v tests_stdlib/exports2.v tests_stdlib/funclass.v -R tests_stdlib HB.tests_stdlib -R examples_stdlib HB.examples_stdlib -Q HB HB math-comp-hierarchy-builder-4d8a939/build-support/000077500000000000000000000000001521677141400221675ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/000077500000000000000000000000001521677141400227515ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/extra-lib.nix000066400000000000000000000077721521677141400253750ustar00rootroot00000000000000{ lib }: with builtins; with lib; recursiveUpdate lib (rec { versions = let truncate = n: v: concatStringsSep "." (take n (splitVersion v)); opTruncate = op: v0: v: let n = length (splitVersion v0); in op (truncate n v) (truncate n v0); in rec { /* Get string of the first n parts of a version string. Example: - truncate 2 "1.2.3-stuff" => "1.2" - truncate 4 "1.2.3-stuff" => "1.2.3.stuff" */ inherit truncate; /* Get string of the first three parts (major, minor and patch) of a version string. Example: majorMinorPatch "1.2.3-stuff" => "1.2.3" */ majorMinorPatch = truncate 3; /* Version comparison predicates, - isGe v0 v <-> v is greater or equal than v0 [*] - isLe v0 v <-> v is lesser or equal than v0 [*] - isGt v0 v <-> v is strictly greater than v0 [*] - isLt v0 v <-> v is strictly lesser than v0 [*] - isEq v0 v <-> v is equal to v0 [*] - range low high v <-> v is between low and high [**] [*] truncating v to the same number of digits as v0 [**] truncating v to low for the lower bound and high for the upper bound Examples: - isGe "8.10" "8.10.1" => true - isLe "8.10" "8.10.1" => true - isGt "8.10" "8.10.1" => false - isGt "8.10.0" "8.10.1" => true - isEq "8.10" "8.10.1" => true - range "8.10" "8.11" "8.11.1" => true - range "8.10" "8.11+" "8.11.0" => false - range "8.10" "8.11+" "8.11+beta1" => false */ isGe = opTruncate versionAtLeast; isGt = opTruncate (flip versionOlder); isLe = opTruncate (flip versionAtLeast); isLt = opTruncate versionOlder; isEq = opTruncate pred.equal; range = low: high: pred.inter (versions.isGe low) (versions.isLe high); }; /* Returns a list of list, splitting it using a predicate. This is analoguous to builtins.split sep list, with a predicate as a separator and a list instead of a string. Type: splitList :: (a -> bool) -> [a] -> [[a]] Example: splitList (x: x == "x") [ "y" "x" "z" "t" ] => [ [ "y" ] "x" [ "z" "t" ] ] */ splitList = pred: l: # put in file lists let loop = (vv: v: l: if l == [] then vv ++ [v] else let hd = head l; tl = tail l; in if pred hd then loop (vv ++ [ v hd ]) [] tl else loop vv (v ++ [hd]) tl); in loop [] [] l; pred = { /* Predicate intersection, union, and complement */ inter = p: q: x: p x && q x; union = p: q: x: p x || q x; compl = p: x: ! p x; true = p: true; false = p: false; /* predicate "being equal to y" */ equal = y: x: x == y; }; /* Emulate a "switch - case" construct, instead of relying on `if then else if ...` */ /* Usage: ```nix switch-if [ if-clause-1 .. if-clause-k ] default-out ``` where a if-clause has the form `{ cond = b; out = r; }` the first branch such as `b` is true */ switch-if = c: d: (findFirst (getAttr "cond") {} c).out or d; /* Usage: ```nix switch x [ simple-clause-1 .. simple-clause-k ] default-out ``` where a simple-clause has the form `{ case = p; out = r; }` the first branch such as `p x` is true or ```nix switch [ x1 .. xn ] [ complex-clause-1 .. complex-clause-k ] default-out ``` where a complex-clause is either a simple-clause or has the form { cases = [ p1 .. pn ]; out = r; } in which case the first branch such as all `pi x` are true if the variables p are not functions, they are converted to a equal p if out is missing the default-out is taken */ switch = var: clauses: default: with pred; let compare = f: if isFunction f then f else equal f; combine = cl: var: if cl?case then compare cl.case var else all (equal true) (zipListsWith compare cl.cases var); in switch-if (map (cl: { cond = combine cl var; inherit (cl) out; }) clauses) default; }) math-comp-hierarchy-builder-4d8a939/build-support/coq/meta-fetch/000077500000000000000000000000001521677141400247665ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/build-support/coq/meta-fetch/default.nix000066400000000000000000000057311521677141400271400ustar00rootroot00000000000000{ lib, stdenv, fetchzip }@args: let lib' = lib; in let lib = import ../extra-lib.nix {lib = lib';}; in with builtins; with lib; let default-fetcher = {domain ? "github.com", owner ? "", repo, rev, name ? "source", sha256 ? null, ...}@args: let ext = if args?sha256 then "zip" else "tar.gz"; fmt = if args?sha256 then "zip" else "tarball"; pr = match "^#(.*)$" rev; url = switch-if [ { cond = isNull pr && !isNull (match "^github.*" domain); out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}"; } { cond = !isNull pr && !isNull (match "^github.*" domain); out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head"; } { cond = isNull pr && !isNull (match "^gitlab.*" domain); out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}"; } { cond = !isNull (match "(www.)?mpi-sws.org" domain); out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";} ] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}"); fetch = x: if args?sha256 then fetchzip (x // { inherit sha256; }) else fetchTarball x; in fetch { inherit url ; }; in { fetcher ? default-fetcher, location, release ? {}, releaseRev ? (v: v), }: let isVersion = x: isString x && match "^/.*" x == null && release?${x}; shortVersion = x: if (isString x && match "^/.*" x == null) then findFirst (v: versions.majorMinor v == x) null (sort versionAtLeast (attrNames release)) else null; isShortVersion = x: shortVersion x != null; isPathString = x: isString x && match "^/.*" x != null && pathExists x; in arg: switch arg [ { case = isNull; out = { version = "broken"; src = ""; broken = true; }; } { case = isPathString; out = { version = "dev"; src = arg; }; } { case = pred.union isVersion isShortVersion; out = let v = if isVersion arg then arg else shortVersion arg; in let given-sha256 = release.${v}.sha256 or ""; sha256 = if given-sha256 == "" then lib.fakeSha256 else given-sha256; rv = release.${v} // { inherit sha256; }; in { version = rv.version or v; src = rv.src or fetcher (location // { rev = releaseRev v; } // rv); }; } { case = isString; out = let splitted = filter isString (split ":" arg); rev = last splitted; has-owner = length splitted > 1; version = "dev"; in { inherit version; src = fetcher (location // { inherit rev; } // (optionalAttrs has-owner { owner = head splitted; })); }; } { case = isAttrs; out = let { version = arg.version or "dev"; src = (arg.fetcher or fetcher) (location // (arg.location or {})); }; } { case = isPath; out = { version = "dev" ; src = builtins.path {path = arg; name = location.name or "source";}; }; } ] (throw "not a valid source description") math-comp-hierarchy-builder-4d8a939/coq-hierarchy-builder.opam000066400000000000000000000010011521677141400244060ustar00rootroot00000000000000opam-version: "2.0" name: "coq-hierarchy-builder" version: "dev" maintainer: "Enrico Tassi " authors: [ "Cyril Cohen" "Kazuhiko Sakaguchi" "Enrico Tassi" ] license: "MIT" homepage: "https://github.com/math-comp/hierarchy-builder" bug-reports: "https://github.com/math-comp/hierarchy-builder/issues" dev-repo: "git+https://github.com/math-comp/hierarchy-builder" depends: [ "coq-core" "rocq-hierarchy-builder" {= version} ] synopsis: "Compatibility package for rocq-hierarchy-builder" math-comp-hierarchy-builder-4d8a939/default.nix000066400000000000000000000007041521677141400215230ustar00rootroot00000000000000{ config ? {}, withEmacs ? false, print-env ? false, do-nothing ? false, update-nixpkgs ? false, ci-matrix ? false, override ? {}, coq-override ? {}, ocaml-override ? {}, global-override ? {}, bundle ? null, job ? null, inNixShell ? null, src ? ./., }@args: let auto = fetchGit { url = "https://github.com/coq-community/coq-nix-toolbox.git"; ref = "master"; rev = import .nix/coq-nix-toolbox.nix; }; in import auto ({inherit src;} // args) math-comp-hierarchy-builder-4d8a939/etc/000077500000000000000000000000001521677141400201315ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/etc/rocqy-hb.png000066400000000000000000014322531521677141400223750ustar00rootroot00000000000000PNG  IHDR6X9"'iCCPkCGColorSpaceAdobeRGB1998(c``RH,(a``+) rwRR` Ġ\\0|/” RR N.(*a``K @ [$)^bdo!`5 g ͗f3K@l 蘒򽆡&~ JR+J@s~AeQfzF#0Rþ9ɥEePc;wJfHŗ8eXIfMM*i6.@IDATx`\yy*g sdn,Y֖-=#]X-[h<4dIVjN͜C3g$H*T{W(dDMD+(W TG?i@5 A " " a<6s$>s\," "0<"&Vg}uV!" " " " " " " " Yp αzX)V? k=KCD@D@D@D@D@D@D@D@"`N'>ƺctcs{Z]'x8kc岜vPЃ2?|8|ڜN _/eY94D@D@D@D@D 鞸ͺH@*C5jV⫹Q5~t~)#>q3GxG gH|gn.TD@D 9g-`)rDN[X(9x pB-|wݰv< gH|gn.TD@D`od=띬YXŬ tʋ9 ):5Pr^m&SN~-' ic]:NVY&:YPQ*.`{]s+R@рdG!*'gXSyF_D@D@D@D@D ɺD sX%,Gt2!<sBu҇7|:b7֪gB3$>3Z*" "p fM:WnAgPUC,삗S_tR\(yJq㴐LSeHHlzINA]!T vQGݠ/-dx(FGEUn?&" " " " ӍħvGu=" " #p n2V+n ̏b)[jG):12TXԍh'Y c$KCD@D@D@D@=OE@D@d-oXbd,Gtja(^7:)t!ag%Us>ձXY" " " " "0 H|X(" <J@i=m?GHWul[Lde^gǸՠ yQ/*8r~dYƔħ[" " " " ӊħiu;u1" " Xv &}y,x7'0Nt:l "8dg蓉O\c8q6G}e, $>M[ {@.rdYk]d9SUYEjn~g:7W{N';wU2^nN?t% iY][䴳mࣉNXr26^rnE'NvΌ)pKyȲ'G⣆L[Յ=ALY,ө5Z {\ao ׍d J<}^ u"E@D@D@D@D`4]אַKD@/M:k{UŲ:yBI fdVu{a$Ƥ{aBWqŜC{G-f%V! iJ]L{j 6X&:Yk]2-JՖYaԕu#s9cdiXxnăbp:r0Ҿz]D@D@D@D@:OSj" "0 XkFf9U贳0DylbR4r>Mİ z-1˦a⓵hbi% iZ]Li&Աְֳ4ZgNQ ftNɱ.oZ8[寶AO6Z$>Mيt$E6,<|5mTֵ6BkS%~lVcZgYMn~I1.ۇxO?vHϜW/Z8TcRVFhۜLM~jN_O#VR,g[gX̬ (ka֍ބ9-щ+$<.ϝ)ܿ< ny vz•F*՗eudգL7%@S'`Arjm b]Nk(+0@j04Vٱ=@N` /"AS?{$z^yrpr8? )oKBmջYB$ iJ6MZD@6VYVg4jp^4V9M!Ԕyό'2&S\~-oҎN:ԍs{љrZ'L M%L?~xy->̠Ⓣq%){RD@D@D@D`4n+" SJu,kĚϲ\m;\F>.Al:B\΄&8i,#:Fin<ur{ =)v^?EEpwpH%:lԇ9Zﲦ E@D@D@D@OSni" "0 r`e\Na9B?1ǩ9 EnK$-ksNt5O~ {PtBw|HB-'Pذ 'qt^;=tF]EiwTwa5t氚XX" " " " "0H|vT$" N*YXŮeڃg͖!/r 1TiXskkĎqlځ퇺pJɅ@8yUP0W"Wo0]\U.ũ]pBq?pk+6w%)kPD@D@D@D`*P0&L 7d},\NʋX"`ǩq8qBnڭ8~>me7<كKW:.X 6~-B V$[.DAz;]DZe_7C BO:K.ww}zgOa6$ ij7ZD@&@'7wzVk0)`&=[NSM1s9 BcVy8D&+]#jcq>g:#ZЀPT?b]M銀0kbi-ZLtrlA&*3h0 a[Jtk]);;~O8^i;Õ<|r桸׭E4&ls qo7(bn[$'Wβ;OD@D@D@D@$OSi" "0nL)c2i9|4A nQYB0Q_壣\N.j҂S&Nvaݏt#m,=8ז5&'&W,En -@0u1vyq:b.Q`+W}S7ZE4ΓŮOe\nnCkD<>jX߈4 iD]0e;lu6gx:51@|( ԋ;D䞾1l<7N\mضS)noy _ᄈG22)7=i5~DS2G&pt/ 9;Z(jyg/$BLư1&HO'ZnP}u)+YHx$Q *͍de9EWK_E:9R@]󚂣:ZVì ŧrV~J4D@D@D@D@D`4o.@D@&`7{,BHkG!╅^nx|7..'1 )>p7η-D硸a#k"R#LtJ3&h-F׺Ncy#܈^C;g^kNԍyA<=T._ƲWϋT" i*-UD@~enzVŝxNgQ< nELSo8r[nZGi\G:ܧ5pasYj^VOlջox!" " " " Sħ}4{ `mdULtr4;*KyNKgPa!^:p1u:ճt ." " " " ħ~4?Ȟ9,IN+٪qM _3?E-!ԔyeN' c9mn ֦MH)?,'`{ t9u$M0.FխA>[r +"|[[Zw'xǣ++WոzaTDGuD~H9,ħQ" " " " ħxW4')^& -\Mm´TUE8f9d+֙$[ҺڞNv-.Xg Yp+r,'f:s q֍wkv;+zNگub,l ~ĄbޙVZ7VKCD@D@D@D@,OSi" "7|.gXjY^ /F#na t(0D\7ܦrz}_7vJXS<-"\vע~= GN|J\NN,Հ)\dz4 ZҊz=8u>j_Vwv=vQAkn{; KCD@D@D@D@,OSi" 0Sffz*d9V/CAnQKgQV8+ى-V{t/׉-t;R\Nt )MlW[6rʟ.'^MG:x<D[m'^Ņ˽s4O7Oȯ҇O I|3=-" " " "05H|I#`SV{5eYM2ZC@iٜ0AtʸѴ.Wtan,.f9%\Kk UHr"S?Oz9b0x<E.}\#=x`ZJӎuI Xm8IO@ӤE8R9V3D'pU 6-bEk+ *d:Hs9u[w፽8|2WάXGS ylۀU5,dZie9(z#RԂHaي7Oqs%T*A*t.Xֻ 2lfLImӤE@]2,!E'*ذ$5 u!^Ǯ;s͠.k:VgDp+ֽFӮ8KSe9%g9ՠֲ;YNX)g'j]v y\ƃ1LF&]ќD@UoYY^7e(:-HN U^t2NFmI<ԃvwn\iג5ŊbsM,'?IpҐ3?Nٝ)l=zX?owѢfs}[z{ ^:[ *b]mtSzgz!" " " " Sħ)w4aiH-neY{F^v: SRpDt;54빘G$)8mԅ\MQɈ2."ȯX ȫ^0nM Sm ~#Aq|?t>r*SҊq-cgj9zW[Gew[]k9Kh@j[IC@Ӥ=Hĥ'XX ,[`&:Zf:ͨv{NөIl߃t.'kcSr 0Kf;S~Ċf1稔+ENc2f99~8Ga1;6zG'ŭ>b9f^rP24߃OcV4Kw!" " " "0H|ZK 1FV-D'G V̍`9ݽLSww?r:ESs˩+Q԰ yʭ)m@2(^$Q>)hv8ڮ;yOaQdu^tw7|We" ~A-p%L)dE@80翊e+m`U,PQ&RWš,Fm1f:MXgPݴp^مGs׺RH ,)RЄ↍(ۈh< cwTqL-ñjOPu#]7_No#n3st#7*BԯӅk\o><-Dz|FCv?Zpmz%hZYf zSQ/v$}|e'B$>MYL>+1BGX0i~szSyy{.qźbݎ. u3:b]r0ˉ.* +PX9T O na.,85!n$iz=)|ɛw%.,Ư=s>$^;0N(*@ +"vً)TfꝁTWs밧=MVKCD@D@D@D@&=Oi" N0DV9ANE^@9LtF8ZC\=5V.;{u,QG!]Nի.ASq9huw/ēgS̵-;ߏcSB y~|t"e^ۏHl PKpp<[!L*^1w[QAl?IuXͬ#D$ 54D@D@ `^ֱ~[fg DSbheVOAqN4'<^n;3_{*t;^8V"5(ky K?EDq&D ġ)qGQSŸi+)s),j8x:{.{xGp1ewM.Pa,*awnfhv9$\0[.Vomz>Hiuj6s6" " " " "0|;Lv&:ճe*fX#'7V ӡ@aN\AdrxL^`ޥ2/NIqpq;Cn<7>u rr6Y~S>=e?\ y%4R]L?~Ӎnq:>~/{p&enԖa"ԗn~ }^:+#Una8pG1){̏ys݅w=GۉD4Qu^ND,k{emN&:QIN>d:? s_UL^^#6>uE{:.eKC[yC bXʲ, $>M[sֱafLt`J@EQGSc]ZXu|[w b<у\s+;+Yx7X9jum⻯&oyzWW쩛}PO_hHpׅnV?ؒaV-vO7Wlp/"J-MsDΪwOA<2]-SO/XD@D@D@D` H|o:d `HլMY Ydng;Jb!7Xή~>ՃWvua.f; ]N<'jcqZJȯY<Gp3W+ytE=qdsX mH{*R?pԱ>]9!" " " " wħR,y&};gXRsmsZ<;Mщr՝NZGlf).e!Q6 EJ_!!b99S::ZݸoēgoYOzgXNL@@92.'H7ُvn OCs{(l;}8W0Lb;Oh0A㸟ħwF֞QJ4u2 @ X+XcuֺH|_17tT29psZgaG$.G|ݪul[2 `Hi \VS7Du5nP)XVSfd4Kgx_V>_1?,Co?Wxd;:/jK$_ bIFK wf{Wo39V',msk]I>D=<'mn§- )ZW+w'jXXACD@D@D@D`r49f%" :g vZgn`!~,h c]NXQAz#ExU^х7u4[; Έ .#(ZWjxzTs2gNfLۜȋ!8ջos>c>V‘/UϏQZt2a03v+fd~M:Ztw |%P?hL綏>50쾩:mVb4 +Y/4AuZ1#`ɺ5Uqzh `Ŝ#<Օyu0*6Zщ Jsck]oֽ]8s8[\.VU7~bsr*gk] .Y.|=~<݇?B/*hpۆf/$7Z2DS8e0/r{7t~vNvWnbG|p\p#fs"{_`Zż!8V~Sf泞8FD@D@D@D@ƛħ&0eZV-XLTE.a68f!u?lMNjrq69mq ml5ZW1 /_p yt9Ysj5OW,YnglTpYPO;bexs&xE/%o `*\n][Bi}@WOq-/Rݶ ә@A$x u" " " " "0$>7qODn޶Bz㬕2V IN\YaKftN5~xsȌd̄_`}x~{qz>۪u5PlUat]N1 VxSmX8#K=>WaNDI55B+OO[نwDqF/^7t/޲Ӱ'=*9\s]Fl>"\ꅽ8s)=oQMi4s9+5qqsU:5ci[_1#CD@F&`md=ZƲ<'aR]Zb Ou fXIk4"~|/+\8ڮg:(]fN+ULUDE[<!ם OcU} ^} 3\\1ϋ?a+YNCWvjY{Xk Q\O%wk8w{K"n'rݕ!.79(jō VA9gZaWRSP2;I/5,[³fx<هoDOw")ͧ$ptu,R{ ;=]f7.0Df 62!?hi+}dc*ZL_B]P~v( |al6/]GY 'ndbK7OiyR/g?^4ô0v k{|㥽ۭ1+V:9p|?%֍9p0^e-Zħ(_š9ci[kƚ/"vdD&:eSRD}./V/c?yV5;3Ve.uCgxcgֺ3'D|.J΄7X(gu9IƲr.4%щ:Ï5/S!)]>D9wvŇcAS+=eiTX5ۃl>O(Wt?!̩DAZ\:#d8؍WFQq>°M̑`~Sv=ߕjZħe% i|yl" f~\gKX6+0f2D×l:.A/YMΧPHyN]\ƾ.%p. j)aG{ wFq,7^momkCzqL'>ջ Un7~8y wԷzW{:Ξ쩵ֹiXкgSXE"b2t‰s =GinhHˉj 0|=gB>VKCD@D@D@D@&O6h" ߤfYM,s:9VYreIG5+r"'+8mrC2=saK"9ۖĖ= q\ Qvgi˫شN[! N<ykz?<5$l=(t!?^?^nǑ>|Wҳ^ޗ;Y8y|T\ţ=K7Fh+C9{|5#r#>]jO bneSB^Q<>mֆ:e(JD@D@D@D@ƞħg3L-2Nz29{UQtZ Ut:Uxm+ץţHdێ4x?Rhz_g ]Hgp:Byf<5v ]">PtI}hhb&z&|~9pݑo8.^~N_}!?9?ю7ҘYp}4.ޒnz){aOE\n->{G$R{C8y|/G#n,j'kU%,4'=@IDAT4@3{e7-f=Zϲ|ACgGUYktZAS=EhӀci4ug/'p崏/t9%3u FJPPE ϫ^Pn ]N19Zؔ'_TNQq~sqiBwFqݛ>h?eGsj\7~}dڋ׋I% -//paC$ZꮴZAtт&ۍlzmtNYPlqa1% +Y&n@PD@D@D@D@Ɛħ1Cܒs> gD'sk,&:ՖvE9t:{6(E';%3wvɸ#8mc鋽Nk]Wϐ`RpJCA}E0\?)sX9eQr3Tb0^“ku߳փ-G m;2\OCpąCS] U?I8b\r%cc+ݵUC ˯YOW;u_ÖϑeXYQCgLxy?kk &).ֲ5XGz^pGt0$^ E' GA;[StbۘN2W,dj能/CNB4ݏ|f:EҫylDsSt@15ϦRӇ'&Nx&/* ܘ]W6'G6vO?v|Fǒ_4ͯ16x܇juyG3Ny8GYn/q~P#vfϗ$yQMx\zW[NlBYX" " " " "0,BCD@ƚ% c=9h9KRK]Edv%׋NY@˔Ψxo:]lcĩt9ݐr{+8׭AN<WK!4FYqo2QhFa|‡\%n+O|]Ŝdm]ƿ! % ӄE`0*NY׉N 3C]NԛvNy 5>ʸ\nȯZȩXp^-\=ijNZu&5cV y9 4/bNϹJ\ТzM28w>u݉^gvmu8&ͺ[Qϋ H|=3!"02s5m`YO&:Y{3B5~~QRu8ɶcO4(a`X2EZֺ /桰~#Np1ęDAF:)1yjJ~iuaAQKuoB'xr?EVo?v ;W3 e?8}it$s4kPc~~d+]oǽ(+!ʕy-i^-bcC3Bx5G|"u,be4CiSK7" ((ۖymևXXU,n̉}]ks0wfa}<on)3@{/v?g߸'h)a9+֕d惨[aT/exY tLmN8E^;r(@e 2dVx\?Q=A^߇}.t>>Lw?R6yc><3%?޷ދ￞?<9¶NU;o9=^=Wʩם<2 sF4Y띗G]}œ3YY[j]& ]É=JNkXOֳY13ґaa ()9f[Zh^ޅm;<}i˴'Y^S%~Dx uGOZ?`k;s:j'!@w:~%G𡇽W_H7pP7,NtKg_D `Tߩ +{[@>k-3, &N*ӆ@d1 ģa/aqڈ.ȀgGt f l-D~nlmNj;n]M:e\!nye Pa /?p2M#NJ7ֹGÜF5J =4yu7b{ֻ2޽Ƌ 8m(uRöARӺf̹+q~{9﷏|*ti##BchkR97Y̱hl `.7 ~d gQ߱-a?߯~z2soKψ4>uNe|N6p6.6)B :)Z_Nʕ%u3[ sU(j|yU+ɯeSiBٰ~Ǖ\xnW ي%<G@ .gz}c5<ۏ?r/|5ƍ95.,j8R&jJ~-k<(?;-^Ʒ)aVnt?#KfC"[ϟDQP=2ع$kCogrԞzه {a ACD@D@D@D` H|:LUr0k#elۜsC AaE'!Z $]f+֝Ћ!!J5lDqÈUG0Rֺrs9M#ɸ mOdVlLar]y*yc_/(0³yxZ~4U838֏H9N'˻)G wrdԂ}(r"DƠC=4{lue>n2 ,xy,~q' iܑ"0؇Wk{k-evKѨKÇ&AkCURdv mcP;:WM WbHu*`M(0T2>{NyZtlSkopynW>!_^p*`z >׺g2'Ջ .< ճx:/ ~6low_Y`U.8ˍ,ty3D f b#>]La;ŧVD7~25Qʼ\:LO6/I(" " " " Y$m" j"}`}e!y,{%>Ez^ :.̵ qF41']f~J.*[^хlZaD^B\gyNyNl,mmdEn, O.(k6xnnw.84Iï/ N|v)]lı 'dyxk](R:9nb2j|[k65s\mHԱ_Qzn8}s1B q: 9廘dJz|$vÏ,D/RF5hxNVX>ZVWT7$>~ͨtXYFnq.Sq8Ε"lhA^ޅ(>Oz5c+O['II>A&,NkBXIV.Pp;qYSt~8Mt=G{yk2̅^Ls37lDxb99V_YjBzuش÷+:NQҹvk WѻĶ&ߊx}HL:M\Źi; nY>~V׋Ot sEY;U+85WŐeCc+9LD^ +#zAD@D@D@D@nI@-̑z'k]ˉ ?CtX>/9O+jyԱ!`h;Թt=.WOm]8wsrW>%3E!E'|:n҂t柗ޑr׊u7/Ǐ߇ 'yLeD O6˖tՕP<:{δcĺq\Rb9y7hذ(R,Dq\O&t65l'ǮGV=]E>=O|z!D6OZ'ICZpdYB c bɬ$^_CA+q9{sUFtr7?ru{ز/'anMv-"rmk]w[a SdJ|yMX>Z8gMCSz4qVV#{l ]K?s1^Xk8L z(-_j/ʱ߀BN\D ~v3Rq 6awy>4U(> Y/g$m)" " " " oħPGBYV\\Z:#-!ZDEa|>Säu xW_g!r]z0X9\u\:#[I).O< wْoEۏKxIMc_<ŏm?N7z3|O 򅡹7~|{J]l939"[Oȫ\O)>܃J:LeFqZ[mwjxu73lRzgH|r`x4^u8•=91.9=TX2;* \N<)ssK%i$։vwp%^NpDH1 7tcȩX@NiK1' GI N_tT4iƒn$m&jdt$EƐym,oW6'6߃]G ]7>U-`ǻٶo}n.|ޝ%ƯE9Cijb&WaۜUlJD[ϯgD@D@D@D@D`lH|:L4dlt`-bC3V1iqs^ d[.;ota<ՎɎTQ8r+TĶ<i_}7l y{nGk-Wxؕiٗzae'kٍ^lom ?9ƚ=~n/ՍD%vz=n]!LJ n޹DK V҂$vfnxyd-zO" " " " "0v$>[Y&}6aֻX Y&:X=\=U\n ?dxr&@>Sgx`O]Lb'L+ג9B."szeO +x\cRLh8d*Re^'}bTfJxunyX3;&f>DzVճ\ P.rQn؅3#뭇>.E_OSsK,dܨ3zhOogD@D@D@D@ƈħ1Ê0AOLtLĢ:"X1ϩ(7 >:q^X%f=׽_,>0Q4‰ ÇKsc=ڒJtܫ#gLԱL5Q6:kgyݸH?sHs[(+8s1'zQeHxbf[sM9/;+V>_^"ko6D@D@D@D@D`H|#:#g=ɲLD<fG~a(dq>esZ /Ə_chcKP2qY;?8\wdN%5Wv x]쒞ߨw,e{b0qOƲ^O44 C44 Iԋ tVeI;SH945~.;NNTr!ZCwt)>_T:tdR?Ҳ&O:%Y@hKR%YvʑA keTWZ$# ϝwH[5ȵ4T`03G ۏ?N/Or+/,)r)`ZfENQTE.IɏqݼDebM63lV͙t M>7=HeD*$Nw4F,xt$m1(đg\蔝Geω6"hSLr$?* y$%@iWT((1-c*EF^:j݊C]IB sH:T:Oi*| ~=v5+WnF6@ DvF&fʝ*(@qM>! :ttttttttF.|% t ^;IV[. KqNQ)LT:s~A:lEGS))bLVɜi$d/И1þW҉M~ǢF0*~Jo%\Fo(mkPe|)[wIuLgǻ쵡+oџ>cdK)K8pޣkz><[X#T_y~Q|LQH4^(\@AFa08^XT@ ߤ~&Bm)Ql N՝RoVx~s[29?D3 lա3333333330 hiӳ !Su@qsD"A픗a(x5zH'D8DMU4|fkf.g/[T6f3I''Ãvxp3ܯ0~nYvwK]k ^_ #!aYxH@fZEPR*_vU26t,+ɨȠ zc>P;rɡ|MO%Yˆ6tzx&sF %)5gSL-c72_һdʏ94   hiDҪ3oc-(@҉u覺 $Nir[$" u)7=GMu}IL5mNE?wfߏ+sc+|c .B(J1vAN*#, WI^JFHI'AnzxTPïTC6QA3P )>er8ÂI.UWbbR?o4I!\Oܯ] H@MX$||WF^l}gTNxm}U$J'(5qtT}u7rCb?x,X"e 2i` M>5=΀ ̑H:2%K`'6-&ΌS#TPIn=!4smR].WDl,I1_uel9BT*Ûc*hȞ?(s$H\# Ep!r"ZrreO6hnL;0h IС333333330~x30^3@7UO,]1pԹ08y(mSj'vF $LXY/) a=Ho՝=%v05Ni# H HBFS56q<_*i UIoY|tC^}L >ezrk+hW>ELO s@' ۯ?w ѯ:::::::::f .]O302tY`52  R*|Q"PѩlՋ TD.<"M`$hlb #lqg$fйf[ Ww~ً\i,%@49ޫm4Gڎnx#vXZ ɦsӷi01!Jds?|Kwd;8޹J*HBeQI 1UvNdA{/ZwٓOD* 2I}!vKRV&/3"(xM>qN=]tw#:,@n5`:ttttt~[2ɧߖ=s`/2<1,v͎ N$TSoGd&\!u( r/-+$ez[D"H'trVLyƠf=n9t;#m((ˠ77n}=xT6& bq*GMr$;[JXV /AI@;~ W ~g"oUo7a6'o::::::#ϔGhMz:g hv&<-QAX4N/</ϏRP;6;Nf749#A<5*⩥͡:f[N+%o7PfĤbԫPs}~8ٰ$m‘8:) V7S󌊀8ݓcrkh{K7/Y*}g= Tlt40YdGgÒ>oMĩ2 &HbK7,2-8_HBZM]KV?)̾}O2$ A"q[-lAbieCyLBQ. sB ['kb7)U$)hqI')Z;Dlߖ6zj0$6s>- 1U,Jpi:ܮ5mXl{xϺ$XK>m$!)v÷Yfٶ;9S z[NIA3^L;Xwjv4T]}wXwQE" jC<PUr$i~֡TL3~P=['N^THj.oi:PT*DOa O%x EO{/d?>8)l6KffL>]$99YVxO>Do.ʪADJ,Cg@g@g@g@g@g`3ɧaL^}nyʧŎe.҉o`̻hj<o޾Ntԍѥ^w7ʁS-R]׍W):}LxNIhL"vNHPadOW$Hb|!zgw/?=\{ WeIMBE->KQa"UyUZhAv;PE!I2dUJ$3OFynEO>9 %.'XݟzO344gntL ʐ+rS]GȧM$2$slQv;˓4$o2@g| xHiѢEH^^DFFu œ)ƍ#*Z@΀΀΀΀΀0e:t~3P^$ԟ&vм(yve,.Y):cRCNՖ:9v 4LJY3%wK|N1zDk}#FTա*: >FTAӟ!h/"=h 86<#mEe(!|HB}p9vgit}G* v-p~o=#MN)2)6,SBVe]:@>&-PP|D:f8R: &440sLygDԩSr9}455)"TbbIEEX;G#qu8 )(@)Ɛ|J2~n1:tttt_iSEeroJQ{tyv,M6* ʓMG#/- <4)&a P_Ms9T\Xaq(] Ugߕ9W+@Ȼxfر-HEz:1@,ֻ %%%ҥKeʕJv!v풪*Ɉ)))QӔW~Q\Q^/9,x(no碍7:ttttt h^&-iUNH(;5TN 9ᒛf0# Ye`g]GdӾFR\;q2i$>"q1nI'хbn?}sn5Z;@~*0?uˇ;U.޳S3"*XSj ɹ&^Go}MSXv {6Nx~;PP Alca, <`fv(HL\i>-7;.qޑ2IYn9;|K1oj39ua@IDATxaؕ5@ej:8v$ 0閜Yv<&olٲEjjjjd7oJee~ƌuܸqWP<^"3ix/ "7O*sco:::::3ɧo4@  #zE١`Z̚Һ$tb9OP|Z:VNrRubyy4IS$"T,!1ƟiFD 䠗|%$FOG>REGxn|]1ܠy_z\3DN_J{4wR$xNpg@EƞzEM5}Kub=yʑ k5Py6%2ױU6,c&fILLE>5Ly+cԿ`XZkDEUAٟMH<5>E*l|!~ @Jk8 x6ѡ333330y[ׯ30|ro4YL.bh[Ttb:N,Y*tbzy{G.Mv]cEJjZ)X'ZDWpg-B"o_wyzᴫȷj(qM`KU|z dC m([R|)+FsrO* .Ye9x.y/\wUVٜ2-7ņ+=9:K)$EJ.`;R+(m%˲9?{.8}HnQDBs@(PqdIBWRpc)ILi„ 3Ȝ9sFqD;DOS@lll)..VP>Q 9TeXfr;g͚%/,_\?GKOOY`;؞ L{ 7:::::L4t ݐa| tM+:F6!B6ǗDˌ tX0٪K:5oZ{.ߐ_@dx?[l0RGoMGs:wo*5;{] q Krы|v` 5J0w8 RS_x^п,7Ũ;3,]w޳pj{rqog+]DXTAA@,&цQ3|WKLpr)\k69dө3lhCnZ6 s1FӇvN&>/X{*|A.$ ;IH>|piO8 a@6l 999ĎYk+0O& R@䃤2ZVE愅)ng"@rmE6߁GxxW,Yg>c(++h WfLfrmPYpG=XA2V:)$V^x3()U@iʛBD{{Ow/E0Sv?S+9bܵxpiryw6OdoTw/'#DJmy<>>A:I葐Ԗ@ DŽa .7ȵr# ~J,;12F8T<o%^Ŋ43dR:?Y'J^iLR09^Så[Z;p^2*"I3X,Ixpu"e $Pzg#&MRd',Bo$# =JēD !/^GՕ( ͒1%,0j4B΀΀΀΀9SNA|҉?̟%<#k@:$#;<`Il;*?}Nh˕Pw_߆_(& 2|r8lC69w8q/+י&ԃP9 c,bi3WBr[Ubd+9O,Ȍc^E T>XxpV∅Z0ߓ|}$_z?,4_>o9IPJQ&ܟ{r! 9s7n0ru!^w=_Sh|6-NytY嫾+FtHۥ֨JOh\aA$[g۰GFHinFr JYCCviEy]l *ڥ#Ll2[%1w,O{ vSƝS8| %YEɘH*j1(((E֍۞>*J(5džgZ$ XΗYӌhGaQP;HH,䔽4Ob il7LF"2rҋ_j\3#Gaw޻/$)rDet/fcid)nU:biS $øݟy0'q>ض1@4^oCy(K HyKΩN77{z}DX~'&r%8ZwK=2 Q16IΌ;kڤ+ '\UZ%^+򱠗PYKKKeTȇ~H#Mj'* n]ɩJ%':4/28ǀ-Lpd`nc< (sfZA`>J $%**Jcaϝ;lY i_1 >y+Vk5w|?PNEX֡333300J:t1e$H<-2U2iHϬGDtbG7=Θܿ2Q]?4Yp;v f͑9 9s~Þ[z:eb'(EkvǣdL?@]ױ`)GFYɹ;QLIymVeq 6G $Rua9G{S>$ H$ W:?`lTAJPNSCw݋k,b.`9H\l"yW_(}Iy8Zr'}| 54[oo],(L-K6rXz;kr:0xex(EL"s$$lpz#*z PTAϤ3 ǀ;%ɪUgƍ B]{x ty=DEN7E555 ')0}x e\l駟6I2omEI6PS8ɧ:E@A "n^( ~B`&0 1$di IС33303Ч[27Qo8oӁo<7S"UiBvo҉쀱vK6i_|M EN2N/y*P=SP3>|Lv>4Вy:/W; 0M!IAaӌ)EdaY_^2H6N֭[G/+'<} J P3RŐ#mlPWTMu@!@+GT*nu:ttttSCg^o( ԗ,gWZx: T^)cT#&O'שrN)$g)!oLܤWhWx&_YcA Q>*"3Z(/x$#׹c'FD~|'E[@>&Hx 6+W[1$[؅&3fw$5rtOAdz0ClqzI ^h;ݝt7=HRuTc!1>nFVn*#__ֱl7|҂MPyV$ xr- &ǥN$6{G#qV% ;{GZf+GU[9äJXN玭Pwe<1,Yp?٥yn$dN DKnnv 4\ь2WtSr٦v-F 6H:Šԭ0 MhY0/0ɯvA؅j ~Ay\tu,ѠV zA}r1mIm ȧKhT5˹vꖢl+sok8!*EYrKP2(J==K~P,$!5L!Ơ'.AW4#Q]hP] |R@|իWٳ|| lz0\9T7CKnS5LZ <,2r>O '[oeعsgtϨu\f~?$fk.)..yŲ_%$N Tp[WR8-Q<'ibIؐm;jۚ|ySVC\Y xx`)8С3pdK|'g$TW:ƦD0_45LRbڃ5YwM{)EUs̶p(JܯJ/Kl NǨv1Zk^IjLG}g8jX?e(BATpԸwM=2cQYe"Fc0K) }a& y&yJ NykXn,G"|iSbV}ϒx{OEcF,1AdSe)eo*}J︝, $G䋫-2枠#qKgBQZjK88%)Ί>mT-bfHT 6jcg1ycu:1X2ˌT:'Ep^nSn^ic$Ar4fb406 پ}PHn?HxN0 2Hf$}SIDӅ XƆ+ ]$T ,ZsrT;K xr\a$uuo6z-鍹=U~UHvHE>߀ɀcd3R0%`fbi 3I51bbVq%I[k4t7mWR}⑊% @Xgoƾ ,xl$2$LH,!Y)vwT4g mwd&)!$03TMIIK%&c"R@:M/>s{+t*/m^4#3Q(srDX}H.7@(Ȋ&(Hy2{'ѱ>Jb;r )2$?cUl';Y&P<HЩy-@͆If) G*N@&oiؾdOї;K$6V,M`qrʃ]x#t IišG*͌ ӗ;v!w.@+32%"0*DK o x̘P^uYn E@SdM AZq  .Tر 7$>5 9A J8"j yLYY_0yd1zw1ӊ/܊'{'^I#)!!9ǏKCJO9\O;xU υGƄR27 ʺx,QU#!iQr@1Ti:tttt Cg`,3 z:}X]l%2grN(F+̴AeRWC:i.Vt/65oYH3[B%`dLIbtJVױ=a[T3{6^hލthimٿ2]f /c=*Rv·'7\ZT902d{7Miq@ZA s,~pICyRI/Pp `'Vd4{1μ$KDI"4?goV4˵ ,"s1A"o,mJCq#\I-.O$sXWPP$Bx7x-^ t2xއeX70_~݌$~0bNI@mefZ" Fɜ%eJ\R Di(s9 sþ7:J>4ӌsן:|׳kG3G)F@UCRcRQ.6\30[B}F\ޓ ݓцr OCD;Z]f ]~Msn#M::̓jW9Pq[1/bײ̭b" Hg8NY['a"Hl_QYD+J TKOʬI!>߯pgJ0 JtJm_ k ++R j%4W UaX l}oe'L4nllTvTd{ o!x6LJ8|RM2E=*UUUwv`G2CK* *;J , =q~ 4ۀ"xD%n۶͉sss?*GDx9pIB0(ɋR%&!ofPn#*$1#\o[*<<;@R.6̤Cg@g@g@g`l2`goھ 0HL|b*O +bБ h8ؒv;qkJޫAwɦ3*CAO sRlZuӲ.I;qti7,ѤR0-٥| }!rŵ4E{-1*PPrzYU5nvu,`*`LɎ)A"Nc SyA݉H 2X>J%*D"ӿ<G #Ķ)@!++K)#+:,HP+O" 0ܞ29f5Kب8_Ӵ#D9mreWZЎ|WCl -*7Tg >SǽL}M7CwkI ޾( 0u-1y XIB*]/PJ*r0 JAf BR$,A쎤0K.&`]$` OjψcvxMU$mلLw 38=<KӚ5k$zH|`HuFl#/(gO^x7p9@iwwwxSSS#ۅlqqqFG L4*cHhZ'J9@hZ+*)={!rK\6| Ҭ y?j+T:o\O%*$Έ`&lfd$C@?sbg[(?X'ϴHu].>{.#ID'OMռI'vɜ[ k;.c̆Y4{ ^ [T״ցiK8 *s iQ&}$!85WEy+!7ow}RDPLo#a_"!]*n˧JyO+J/ |Wn.w}#ya1q<}E ,/(3 JW㣌*}фQ[Ȩx8.w}geT?]钋w@3}c6ѽ2l &4*Yb$!Ogȧv|")I@"p8WO D5_UN* s, qdƌ>RYV&ߏ\ <|ra]HH޽[{=Ayr__@W_-srq3(3Vsα|PP 19%iK8[; a#ʸp5&imQ CZ~Cg@g@g@gπ[{ѺM'?yW>!3po?3GFJ~E`&JI'to=Meב&Sq.Cgn7%6gBä`3k,jHwƟAtGx(zފvka2]䟫e 2+h<ۏTfQ;bAgK<cPqR4kAOFl Y$$;{ݼ^~bi=|sa.#@Ŷ$ ޺\cI<c4ghM,_/Rezg#]|V;$}ɧιG㨐,_$ډƪC\W& x3qQmg`^#Ŏs0㍎{>_IL bZ.(o2bxGʧ;A;O5sT82G;ܠ,I!`04_%`BeuT,b$@%7x,^&¸@&8qB$(#ux|,Sb Œ>ߝ6~ he'a1z(yb}#٪F${Sڽ)cT=<,mN5F L3—5:p#tW37tkK6ھ"Tbf7CwͮqߪwNE\dGއ$[o7:|eHCiq+l7ZdRӇ=U*sM򣍞c^Do%9A$$$*(,kNȬRF qP^@wTxM̱ļw'53  9@Kni2\o6m OMwvhf_A 9$Hc0 )Cŵ_g?$TI7Ad<}ǎ*G;s `sm=cQQһJ<(rO_W/R+@혉a𒒤$Cii^Zjjj(1 [۠"s3`4&#nv˝$ mz 8L;pu 觻rZ7^=< dT:{ż(Y09 Yxc5 )kax|Q.Ttjz-eϗϠ4_0⅔:@WyLعe'VRv>A5MmV0_Je'a0] DW+= 'z:Q``K.Gelr Y7)'n"D<ծ2*K}b% $HVZsH\(cKZ.r[JrPy_?!Yk;Ov;Ӿp.֮-T.}bm.HveM AG`3 [c>, b-)I1-.4~z(HI }Iz|.0 Oc;O ,{L^{5ySME__`=(#ft'NRT*6Tx u\2 HjFizLL~|ϝE$HO(TkJύqr)tO3i::::x4tyaL+HGj0pz,!yi:ޘt Č'j v{M6oꩾt#M#'$`{ez(3ʷ vW=I#|nkrܳWjR| 4>,/z#Po hHny *0pmP|OlO> YU;\+ʶX"~T-l9;avuBY(H\"Tj'j0""I,.˟2J㨎W ps(E4$oB9Q yCv]>_$m ?s.~&JL(bzTvӭR탡5_7ܖPINjp.hrOHnyU *)yC-]|d* ψ7`^#I:t!Y4}tE@qH|M9t|hpx_JP6O?*|AeNuQyy9'9  Nkɒ%2e!D'0ꩡdv ަܹO2qD9r@/6n3{;-ԼڰIrr O~k|Cg@g@g@gɀWin}Lgi@ d^Y<47O-*9bG&=VZ;`|]6mZ(\IɒWHHlm蜳w- IJ#zаpY&#9?^V= dI? +$rpgdU$=r8]9b¶(iBrP?j"cW(=dash]n5_m#Fy|}kJ5+3}^/y)^`T-z_H= ˠkeuk*{ +Mٖ?v<x鴆%J|2:4ɑsmbn$ǘ/CtJÀ3JBtܨ xc2r V\(S$eST %Z;Գj,í`ZSA0H.\(WKQQQJC)55 Rijuk9;C *ѣq7o׫;|&:XVd@TV1PVZ%+Va߾}rc|a v1J2z-ٲe*mpjc^wbhlbhP{᱙?0ن{I'IpPO:tttt 6W@P#R))l Pkz0M/U""q&卨w,F)ݑF9|5z]Kҏ=J$t$比BPZ)08>5$nCnW~FIQ~(!Ċ50D)%\R3"N,m0j9}'YvtNjvXmWkES>%9ƑǦʴ߯E//ǧ+io=8OןMݿFcG/NB(?G'I+U{Tӥl؃Qff;c'Ot\3f-^N:E ^],'&)'59XUwqۆF1{ i{;d1cc!0رc bN5޽;$ EyG'Л~%ԛ㔑F'?l% ORsѿ[oWN4+,ʰ*¹:\~KKxQYicٯ0Jd5];j'.և,x}9ۯYԽuluTz*=8ߪ'޸\&k41_?E5H/ P좪6\ߴOAK.^% ĞNIvE)6et$Uz^`#'I?NXAFĜ[b9̉ xtсȿ.] @i…*ok۳>kL1s.ČjDI"5lguyIJ@IDATg|1Rbޥ0R4gΜimVE9y5h ȰFzgj_ܱߔ_ImzWWZer9J/-/O[Kw~`sbZ߃ZCWC.8'kw]o̝U8R.Nh] Artb} zeD-QmU[ڴFain{HC4t*tz쨴kT{o{*ԩ LdhqCO z Ι&vEa.:o-U(@|HyVsrm^z+_}+9ּ^TȠs9 dZ̷*yqڴ-CslԴhǦ?jT8ggz<':@ښ%8-5iVPP`b!9]UV9q"N@EDJlZM^-4MD}AlBDܹsN^ޥ5 :/*ehỾ%kJbl9/w/>' kr Q6յ,KM2X-#gFKچ{#GD@7?-EXco" D:r}}bI͛ia;)ks+kGϟk bD#VzXј{|)ɪV>(GWwB '5& z_G,qiRYz^v:A@6W0f&ܖV{aǢal1t42}BС;c m@*G8&~N'l@D^1:HѕJK-Vwkht8lZ{ Fy I+-JX9"޵BM8PtþF^&9BF~mmHdb?g+w[uNex`T1XVʋvem3 uz/ok Ʒk'0#9TzY[YdQqmZUnviBOk?mb-E9,btM7YVV*g?+W:U~cϝrI5f#8₹!*Rc96MwYmd!^NGC7 *^7HS[e~"_+Ote~#*"t,}S|5 :)gYci}fۨ-#ǁnH t#jÎ5')ZVh}_#GFzv1.9^Uzwl<%q.KiDs.rp!^**[kݫGzʶJ+{+wu*JuȮִEtys#]#ډ& 7 b-sPd~bYNv|x6:bUN YMiGY6"R.'荈8p{lÆ ^e7a _k9\*()H)sZ86ShM^eSʗ/6Sھ}SBc_t)bVlgR}rx׌ߕO(u/6O“ݥvF;3 ٩/8mFFUDl#G'D h'oCwEp9uNG3bݍSs3K YV @'P:yU?`On{<]*!<]ӷm/YiI/Z4knQL/lXP^:5?Y^U6tZyJȎVFA0oZ$FDPLS4I[Yb%kriȱr TFUzLjKhb$`b@ 'ш-׫(IgjĀMRY"$+VQgO "! ĴizÍپ^tnzr.I%"aҵe]~J[0kEܱ;1sng *VK  4a'n͸>Zf]7 }v"`ȰچGjNNAvo<}S{Ⱦ*F_@{_w[oK* Z75yVW{Jŋ^Mfҝ#6eX>+_-@++_AX 0`X) __YJ.#V9?"+)hwَ9vyvt'2E%rZoɇ@9&mk5nzcG[|vF~6;JZVFA'mׁNgU5+(֕єSdC}ن=+(/Ծ$!@vmgooI` <#խf- ;nOc Z嵿{w[%s H&J+3kT:os|7/e*BYl `AzFyŷ{ЍkЄtùV@fOcHR?RJ\8t']DxPS㴭zNˆV0fC~۲͛gwyKsSO74d.Y''ecJGzPĉ]L=nهxc}T6ZZtkދ9 T]s/€jDA=aD6ax͟e׍J>am+X{o{ӶAW\$}]JS$bd']o)b:1W$}Qbe1p.nnvFM@ >fOtl5-BX;Tݯ9!j&  vҩ*(HTsU$٤V'.xll"nE*u?qhH=JM&sLJnDG:gEǨ>MiT1/7R"0֦+4o0Сt)ތpDEAZ :0G9>J\}حJsljP7~3RLao|sgbܥYVWvF]l0Z-wKӤfw1=%rډ[LgŀA*iRa}e٠Qy6pX}fVĂgmƓC)x0s o+oEyRL'TVVp"^13NkjjҶmf0Mf7of;9,M˛huq\z@(ژ%ά;"U`$LwqNURy 鄤`FT=i׮]X6wNOɇVU_mc--=t_7D¦{ߠ?~>nH<<" n+'/cA@ɲ]7f JK5i Eۺd` ӗ+7*l˞7tc3aCMY;Rs:[KRlK`0Y i9]eA.M;~/TjӴ:bEaŲ-tѥ7}ڕ$O&ܧNO*]WLgoNϼs6:{~n?XXb镇ߓxCҬ(%a]7o짪s qyŻ6 F}"8_c\Q_Pp6rY;^ʶpܶ~p̶}ֿy6>b{ψtLADR ]=# `g|c{\@ȟ#*%yK>\cǺu8Qs'}u,]crb 6 7{R_ߵecRo߾}s :ufʇ!`dL-W{6:(󉸾&D}#G~|h <9aaR=(ncJSWo8'zrz-p1`[]Zi|6:k'*aAa5lfQ5bGyW  p@iY]mA#ž4?D=&MwOā v# K~O*͏h .u+R)SM/}X>*N@x˷fʺ=`!*?^kOJu0z"{D,D%3OJqiezF קM]c" j@QAj-貈@+*QE?4(ŁWQ15XmuU|OUK<2[/>N>97䊊o`N3bZ-p1|}zit,TZ>dQE7'ޭn9HG\+ !DWĉw/ʫ74~y| ¤?~edd8 Kf?|#گ\aQ9S'l2xHNC<@۷Vx~+o7꯮1@9 b>i[ 'D7Z"(L-JGX4H$U]& om5hiuU).V<\]>_\_Ddny<*zzJS5Gc-N`Nmg&{񠾩6''*Bszc?@L԰[;5}C &]纷 lΜ9v}… 1Jt<=Rs[g Yj Nid$J>fSo94B|6Eϳ)FyG_d{Ovm\ڸq򗿴{1֭[O֯_?4yx"BޕFlH e,Wݐn7 `\@H͏?~zh|𩇞jߒN>]_a@T\|OY6|Pfi4<IXjSo)-vxQ[LI˶~#nb7`-KI&eI6cPAcVUV7ZU,ѴPj49b]o?Tу%P^ođ.żzƁ)1Gب-2bZrځ}q &piCs 0U"cT#3ZD;7G!NQm$Գ}G/-z5cTfC)]~IHtID.7$]ЫɶJJ-;͉*FۅǭЇ6l҈4#ݳU7muުjw| } U!s$(,bynvvx6oBLHXU5G[f.XMpi۸ܪ+?^?wF[#G~|E@iߖB>UΫ2N+nɵ2[oבց6 \WVO_7U[ D‘ Sz t8W4"ךkg@0'tj ⳩|g{-$>ihЮr"ܱ:4IlYOetY89y@8]8&B4-5^!E 79*%l43'O0Bhjo.~Qi~ケV}tw7\)Mۋ6nRRĉ[.c[ėTAE#l|]҇ <-Ԁt.dTݫ#VY.vQA9)Lq޶s@F<[Eop`P&]Ffdff: DZE :}cxD'|JҢ-wrP+忑H] *Nj=ӷo_9r;v̥5T7;`Tit>Ǎ4rS|ސ:4L5tPVJ̧b9`^Cf4 c_%r5WYa9{@7HBa[\_IJbK9hG|' M+;v獀NvÄ 8R,3AYA'W6ثU tZ`T DF66/Yހ;tr2tbxLzo!<_^ugGj` 'x:xW`BޱRH['(h3]X٫62XN},UC;C$ep ݑ1zK1P:'` לgXg#L/ ]R,@uĢ-x4)sն?SrKkn5@JIALw)V[sL(Om~7Dt[bg՛5K0%3zқF )x Bn0A=ExCFZZ #q{vdDy y7?~MZDuhy<"11C3ynʷYҭﰥ15o+[c:-9tAhLP"fXɌ[JKctGx}eEW4'1Sv Uwԣ|z0yVU'&Ra?j &\jSt:3"+((3!ZB2,k09&` ޑx1m:Pݡ#_}L–'`~z7e@t*wV5KP3`{u~mjTߴm}( ~Z f}ƈlh{uiV`4mΟ` O KHkDZHͥm-]ilN~2WDp1b 6̥BTj roӊ#C ؓO>Ob0?RN 7x`ǀO:&+|ׇN2'/GTޙַ8 w { 68d5gLEEU}#G>uE;oia:-HӛQYv\gAa}{,@}wy Ӷ켝ibJgC?b%3^ THcznGASlȐ]QIN#uY~̲vj&sC"KQ*@@ɥ+@I@oA~[tZi|4)Os̡ZHぼև9%AB`zReyC\&|8[.X>rT_D+ߥk^=xؐ/S%nUڹ0zeS\r[+(N%j;'_)6qxR\j胀zk#ŖH^JQf2eeeYiic>FH8 `[ bc#O~9o-/ȇ+bk׮%uN_!$y_6***l޽sN@,]44 e'/>lj9Y{^Zz2xDNT-i=tv7c=E's#G@?]{У͔c/3偼͞RncS[(g:1V~J|sՎ _Sv02aN߰ޥK,-wދv>}h]aYaveVțJJ +V& UV[[ݢOk׳bx.Ϋk,=i/ߚ4<}.*ĭR'ˀ0WmDڸHSXmBbc< !|5:*I_q DF%9C!iZYD-ߙ&4I7 jm3` 0$ \KtFxA'6;k>^R9 N0"JEJ;w6J%[ bqms+.u3]+ŷW!Nj2`wQߡGKGXGz0UzRНu|2dK) 'Wߟo֦h/g Ϝ9n۰a=bx+`鰜 H#Mo֭6Ҿ+w M;|<ܹ6fES,+'ɶHj+QV#vp=sqO>M6&ى?~tz\?(moɋ',Pj7ؒY6$ rʻg'G7'iOym?+ًbeA>*~eHAUNy%L=4AJ Z-#\*_|6ⴜbǨ3'}}~q]Ys}GO6Wڞ:yV0c֑7)矴P>R@YZee<^niCGzzlƌVVVfG ѩ8vr{I|ΐt6}DiS}nkϾ#G@"oFNG%9JJM3r:3(E%^GBEn2슪{jsj'\JgNJ@dG.yI(Z^Ao K^Pgo;Ikwη1,#X<sV<})ܯ kur f]XW XQ瀕d )k#0^6 oXT@Xj&hp<7RK)g5>bM8eцbTYw,< ?nw)ǴC[V%Pw쐠=/ЉJzr&-vp'Z@L`XOug7V30>J '@Q?+.Ū׼y\ž:T= ;cNkQQM'7{Ç+6H;85,#'bYUAPϬzּ|$Fl3{mSv,́j?_䀘#G5~|+rւٙa[$ӧ؂6(7(rm6m*__VN{< vCr̰Hzaݵe IkVwgooI4 Q-Oe)6vp `yNӖmwDZk^}M/T[׋56 C jU(s#u?rE߰0e.WNi},"@w4N)jhQD6vx7`8p^]^& Ʊиr~o>`Hr9//TƎkwq3<-m|<[H!{7ѢlϜ9s7t8lN *@;qgU|oRiGW[Q#N9;uCl{V>߶NXEwH#G>̓'+A(۠cvL N<عG-#Յm>Ygϭ8c?}lc1N%VpfwPNrRtj7mfn>T^")ʑJ2yrF2Lgc?IڱH 9 MS;D.9L`\^*HKaEEKG$|ܸqÇT`o ortItNJie[oՉq;֓-}e~z53SN ,Yz3 }v{g 3+Cgp^it5g.ZZstL{4Iw%K͏?~:2>ԑl ?%m >=?OSMnrx`^wX^\]mO\a+TT( mxy~LebX( `yZUk0 (VSoޕb5>pJ}ʆ`:4hx5=b>/P]"yJ˂qD--Ԃ]4RMDCu9&@b>a\~˴A U) ,}z̪4洟`?E{`h? lc*Lֈ'u㋃u1a dGEkpeIl&L9_-{TiLaa_=@/@X rtj;W}J fCl]忹nmwu)zc,ox(ZRiС@ ^`HiY4]VO0r9(DO<<ƌ\g$&_ Y~>ȵo=ȿ+:y/y(Kb7^cݚo7ȴ~Kּ}ֶ>b#KJ{\N+^1CSNQQ?l%3aÖXjkJ׉ y`u /FlyiQX{6fz-v,6^n[{)%& -wdݝԻW72+kv\,lKI>2hPf[(8ں1yRwEڡgTLHd^lRKdcaijsƅ6p);][uIkDxFX @AUP,x>ڍi6̋Vgnx,͘C@îO1yc+%k'=%N~h*Ryӎ5:rpr)]0cPwǫjnFC#uDx58Q*]KHA3,/`l44X\PF4 f x )0c R Vv'+W=-~Jrs~2M>'_ƍ9n~Hl:/:?*?,/h2+#𱉀uaў%||\Uj>-,[8- Mh_ΊTmZwJb0>o%,`*Joy`34e41/J Q`J]Bj蚽_"1bwyG٦Kw'>ybx 'W]OOSI_C@IDATL@3qf"?:paALM%q$~>Hir_.1|pUv\%klVz1Yh`qMr,b%?*_ h6$H*騉`g??c+77\L>3*v;zNyu5O<雉M}S~ e`gۡPk*P~3?@X~߿r}"@7"C>Ejlbh90&Ol6lǏS(/_HЍh>mo\͛g;2@&@)=(}[oUxU+1k"5u7"GDX0VZ'*QBS5m͏?~:9z<"0Z[r)HȦɶn)esmTqf)GOO14GILJF):4ֆLRޥxE>v6=|co-?`K2$wbsCXAå}7/ N!b ; ObӾNtKvݰ^TKc ["GHIUA#%{lm LC蜴DnpCIHYfDikcչFrNw FfTi#ER1sűq~ |y/hm=$Sٻl|08FbcVF\T:WX;IVhn? *\HO L"N K^tӹjw U|[Nt ÇZwL_a]'5..~Rov]Ttjq5 cH_c޽{I[c(~ڨ)lbm!`)N4ϠA\ja~~}ݐ!Cyn?zjx/V4Tݮ)[ޯw6w\>qVn޼ٱ` Twr(Di?~7@C>,9v%T0&ȴO,.8Ut`-ve[m!9wHB/uVԔ^NNShųnC:HLb}P\WZ8ޗb%O*hl_g':N4uշTk òDǃT>ɪOѵ(&nƔz$5!`S My7_Ъ(1b @5AIڱ<:\eMm*U[s9:!*QX_֬Y*|ZdtgJ++*r.qq\\/?G?~:ѦO~擆>8[g-̵I#b#=M}@WVUM't4XSɌǬ[,SSȁNjazޣ=AA]9@Ų3j r,Ug? 樌:@6j˕JtzU0 go^hL&xB\tMӚ^-)N)VF@,"+pDu%ak5w|ȥQ:0b7+c*Z54FfRsS(`"ٰ.N#CJ- ټ !,pU{4q9bO1R@TXUk#r2p\@)לRg5!`5OT=gVX6 vta'HރhLjGN! r·g8ǜ"X4)P;4-ҵTYYɥ۴^Oc?Y2My5PBP}m6~H%lZ|꫶cDit_;fx}smy`nfCP= 0'\k9LG(#G>uB(6Gh]I'oɳc3Oz:a>ym#fZ?:E`A|iyYeDAk%.]Ö?LDeCJD@Z@|$w"=;U7b€< ߿7" ': z:s貰;'Ł6kT9ϳD'*|A@TkPz^AK%a>yl](* 0d[+ @ƊхI!C_G,M2Wl4:\=ih,)DrLc Fɲ#s͕ hnoRg|,nΆnJ}$mv4ix mͯ:b>LTYa.{(#Ma l#'oPD짰U`5eNa^DؘR$ϋvyP@/+_/Emϝ;-q4-S47 )QbO4;fvi[n5tv`FɎjGOjHMH+sҥ_$o}ml2=Y)xN_!b:.ktb@NL 0Mfi"͟.mD3;xi'5hΆuD;bXv 81iw\3X%,Hy %`9|}GeTKKFbF`Te`?6!2)f}n&lJD,t3)[2OkOFFbIsZOylc $1Vb PT}b?%%bw^v qԺrRl8ܚ"P,]6/O:da H,qjgӭ\US/]7"%U/FNweȡcB] Hk^4 X)U-U#q~q׀$h6cIˎ!9mp yg0ͷ O9ZᵵqWG\lӸ@<|ӵxOrԻo=G?D|cN pNV]@E3lHQʥ*Q- nv{BNl]N`\gS~7FI#vg:ti| c/r"U'-?:?tU0x:.I=CdP ͙j1S`C2+!\ xة8Eq8-A齍.% S;i)!h_}"1aU *m `g*ďͦx~x6,9Yr4I\0Ӓ18' @zYK_;D.':mb1X6L3X@ ;qN)z_4}5OKSWhLq3gW[0b)Z^v%/G?PyR<~J$6m!C\rUP䭸sSV]Sow^u0V~@79fÕb 7)[z$R]S~ڮi+z`ﮑd{|`^Vut1V|rnV9s[͞y_SkZpG?~.E.M Z_|HH@lr Y6|PeeDSn31oI/Uػ`:9I;)]` +5+5+zc:S I2wAJwU&g ukWj`V)#R ߼?Z%Ԙ.} @X9Y6ˤ ab[}6J1UVcO48m"[)k0)% 5s -R *GZkͲ0.Tm̈#zJ-q+ta:v4F:4'HI!W셀@;1q4HKܪ1`9!wn(ZUY3u!G?Jz)G3}cz:gs" {t:^y2m*--8gcU}"I($&Oh>~3짓'O?3ݵho_/kJ@X~^?&*~!Ʃ2soH` ?|䣔b>}; _wP]FT!:/M#-TE/?tZW~IjyʓN41SƃF& xb.,%*~Q I9c?]-5'͐s_,`8_qZZpo^Gbѯaj c58 0R3G׫UW!>& ]v׷w%{z[ky~#N 91 6ө;-m~j*9iĠ4ԯuw\d0qΝoك!ܝK"8#(U hVPII_~%T#O=G4S=0`=Da=Q駟vwkSB57?~SѿAa9NT ΏزƸtR9f@NJug?;e};$$Ύa:5N3if:h]e aP962EhbНB4wջJduH)@T#(sOBh&:[vI)}9A #y6 ۛ}utȤ4"}V`}f,%&KHNF1APx81(g/i,!L[澧,nw,X=#o~WM9?}(&HɆ+D;\x]).qz':\ms_@S]@~LU|WH,_qqo%gƵn&n?";Xd WYYi{ .03[~PEJς otT{gm͚5+O忑W}#G? #O r w7ȋᬌ-k^Z` eڀa`Slh0L\XLVkP!`41 *gik{f'bJ'Pک;xtFiIB^WeְK:$z}sN С+ ͧtHEHq: BG%XHtD']*ly;_s~"9bk{-,-[4QtÈW Q2h @9bb SՍ.GX~*uL?ۆ=qQS8~wi m|}};w諱 F@]woX`|W>_{_ gv U%/Ԑ*1~=LvFO}#W;(ΥnTXXOT}Dn+--ճn6nXOG̱?~HNr$ϵ8ߑ|DQ՞ӷۭ7d۰)ѡkyv'^9mx"q1(NXozB1afb5l=~Gi@5g${ r+{4Kg,qz~:NRzVm?x_uF;f8JJ)DTA~J`@ 0OX) Km su7chD lil[$J`+]O޼Hiġ%"Zs_4UlX^E짼<~JM>dggO'uX]=$/3gNছnrSOڵkMsÀg=)#G@ı%L>Zt& ϲSh9FIu62:&1j/T>akuE#YCoڈf*Щ^;,MMhf;7㥏SDjOU\0_9tt8嬨gc@b{6U}ʺv(%Ws5Q!̅'u>K*on8O&0v`PPa/ǒ4=N)~m5þ'4O2&¦܁1F&wǠib ; 3@ bt'[2B(en*ו qڸQLc 0i`mTK쮫msAVlnTGO/ Ɨz'vL=JHE rRyayV!܆=j\Q.J Uԁ.~9a2*ͱo# ]^`]{Mw]P#1lmj}ڷo(*+ Ç;ӓO>idk o~lL~);/Z#:QNO|~I[* ҲX/وn}/Hdw42@ٿ `Dbfoab0*12( 2r0OeuU+K;R u f[G; PQ$ jT:ɥAm)vՈKX9TlVfJD1 b|c4643 rT60BhA_;OÞJ 84Pmo/KQ4?jɸF8usEJՌV yXR#Nyڰ߱\;G2i~3}xj7 W_uqm͟t)}ZVVG܊ /n+> t>BnVJkE nf gA.؉}˭VRM.z sM U>{^i[Z]]#=$n|o3-g"3+zzІkÖUn|@'7+u:¾vo>9/jOH3ڦ|@_0gh Lɪ&7Q eaW16XLz6HHgQԥSD/OGmD' ;\5~ 9y/@>%ʠĹ>"vOKX,a{A,9Lh5oF)%{JyvX8q.Os>c90bS61&*De>)$!Hu` q/\Aa[i6ώaY/вQ?[B6_G_rboKhS̿Tf|\5 8]ARBzWg޵3'vF ceSz'\E}DnFH|<~:qm߾ݪw5]9 ZOӥǕڐ!C͛7;4;VV <x @rjQjHf k>xJ*:=h15g^#e=Y 'Nտ=WR"yL`]Kz~/Eq:0ݞK-]lBoMI|dn]s~+ Q} r[-6KR*TacXI M+&(+~<5ʏFA '=JU|%ZDwS-) wÆ s'4|IWPgӆ/},@4![c^cRK5@'D/u u.3HPLȭ蒯4 --IB׏ :I->}HN߱c?my%:+H_#gyNޖG}jVa1 jׇb`xqsDICzWA;M2@T>]a(.0EW֤XP|_`g=&+@B h$fOuZĉl f:"Nml=<++ij.CPFTbc'tZjŸ*H1{jtz4f va{QKWۦB[{ˉ >Ґ* -m5w2Pk/^߉GY[".%1g6|bI([oYi]ngOzUr$zbꝺ y*sh4W\.]ЯV;CI6`FuA$#W϶mW ,M~QmI2+**r` 쭷r"jϨ5<&\J)'xt w)ȴۦwV]:u/jTC2&o}tңۏ_6>og;u>U9dwOX^Ӊ 4&ߍ6[F :Jt1+`xMKJJSGmDT5AėnH/TEA ?m G@ WUMaf6,6////#G: 'Xh:/`Ն ,@9\jWP3b-zwD !=$ZQ_CVMlz.xG>nO|¶QG^o'mȜOvM[ɪ^r"H @hooۢvè;Tc"x[;x" a'zi^EkJSZ(hMYI0̠畬Y7S;Vg+5`A^; r &b"0B*q EИ{ZqV$"P)]b >ٸ`mP^C9<|}(WB&>/S҆CQÜ~wi6tѵO;8̑!'2ݱZ^#gya߀~=?9bq}˴o:cQU{j #r,O΄n?kUʫ~jcAMhm_?0lԆ8w1tbNr҆ [6KJ/ ;vlhۢE qx:OV ,@$~įFM|OMR#΁HQ=!ndꍎ?(o= cZOIadbB0|ŧm*ם'"Z]Z/uzAkx;N;o%"v~_monse6?X_k\߽vh9!i'D sR`(=Q C &CUz"Ո˅ylVwNᘛ`<pg?%u>Ŧ b~/GGa=!!HY*&Xç@D45_n;P'`M~9OaF^l@HXCh7Bcj Dx[d?'2X{,W%n٦ʋN^{c #WwGs Cmն ay:uxȞzs?r i ¾V~d?Ra;V[בVwA0=3{DmtYP";]B`W4f5'R6M"T)jw[ې~zcKcocnC~\Gd-H7?u*:`ECk)6sFKi$Kʨ{ߵהt'U?V]KeROn7>dHX<,QR tr '38yX#Éc߬mE Z@wC33/_M /'8g {:neV޼ #"~M}f=Io|MZ=)%#=p}Ė]tǫܹjjw@Ubrϊ4 @q #Vc,j]j]g߃3o4g`5~*5ۯgT,=W% -P^.3~ 4OK3Ok~~VcN;+~B'5lw =^] w25^=صJBjҕyf{WW^ֿC &ܹsm&kl#j;JZ;O{ѣGjV^m[lJG^ehP<x @+4ݠ*RVO [/zf\,Α=g!d"E?JlH~O۔'fuH% +.  Y:9Xb|tķ] Lo?pV'?# aKәV &W{Y &o/^qU ;m ӿTөb,%dzƼ}V/f*%ݳbJ稥k늿=X rVfCÍrsFuPGc;cy}o)PQVgxwvt)cg%{qPo{gۺgY,5 >vU{`)5f+VXO%%%PSL={8ҿx:e&W Vt;R`S wޒtǷ$2~5n<x @fKV =t\ Aӿfgo:f+V􀋽A^6cD&jKܷg ;UJEj>M"vF@զy`SKk(1OIuRR5cф71kEG7Dh#?2EzO~3 )ay\&hS ]OHM&`L?1`V:ӖJb ]wxRXDCFT%klg=@?AJX")H-–  e{OZdnqQBȥ`c[I1u?@8o= 5 @ț̱'Lpڎ^bwUq^~؎Κ-c/yKԎ3#kN?jaTTT8 (,;;?޽H,Aˁ![4e;=zBh׮]k?>|j;_ <x @jS?wjuUӋ=܏η?Pl.=3]k8 gv㮪ȿ1p>6p$$m+tE^tH+K60@)Z-r\ +xdNy} [t$̰}L*!3 `G3]p)?ר|jȲ#o( V ܑS6J)]ԶS, eaiL@?h}Qoа rI0R1(T#͉eƥj\+hr@k0oa x 0jHv\Wj.az˶הq)}-zFݒu<}垨ayMT':F+;҆a0ֽxRfw[]/b"rwHF5BRп|k I]^T V=6C\ZqZ@ձp5_Ur3xwvxꥸ|S:Kĭ@H+((?޽{ȑ#=p)4ƀ:i`{`VZn!cܹƞ}Y[j)wܨC%3j<x @=楼~G0N;[ϩW3Gu8 !1#"xd폞:YU\qJ4+Jii݇kݥteN.ȑO0 7 H'Ḩւ-q7 ?zBwR ZdסzL7 + }3R~JmH[#UV#H.֋ICN֤Fq<\J.)X2?!Cpꭀ=_'@.W**Ma*50H P v$m2jaA51?r_Ĵ @}[IK #c"/JBQ JMNSL:'Q wVsO/ iNJ1OtJm U{Mg s+a>v]܍ =ΖhC/ ִ/U~WZZ(_QQFdgϞ9 @dZ8ҵa,aNw :Tx 2?P۠ց{`< |15)jj]#c٨,@ؚo ˼co*<Z:ˆog-Cf6F骐F]U`UH"?Asx|#ݢrD}3bi:\й"DOFgoɭ8m 1ܔ ~#%u:~hOA{¾16"8gnh,^ו؁7Ucs'ePj}4ӱyg%GXy- .FoH<PEhZ훵N*Lv{JOlDl'/Y'"ƃ`3U&ܱ1 E Om-b0t`hLEď͍jzk^cy`шUe'^ M#=ƯƎkݶJƢ[x Zv{֛(2\Pyyc?9FgN\jtEj٢y`y6-KƏﴵ`=SFA{*5wjXH<}l: 2x# w{'TNk,{iO-'@iG`UB!z}1  {,tj)`Z8 mt@o/}2߰a&D#CL?ow.Jjrd^Iyq/:tF+/;LNF(NU w'O~^mJ߾}^'_cǎ~v<x @z hz<|Dmx!6kB}푮6uxc6ၝm{_{~ ;t" }<~XQN"`,&Nïd)$|[=i):ֹQaxsJ޼"2euYG3@,|OX_]/yfPTzF cB@[5SGлQZE%U (_%`AƎҁ`8< m2O@ a a4TGrR0W}?'vF#E2~|QZ#X G֦e-߰6O870-0uHy[-}*295ćH |7e\\Ϝ`;*TtCQ]9؎y7+ M)ѴޤgoS >S DE~DH5z\TsP߳'vi@JK.˾dlzk49U~Vnʪ:Jۣu/F zh0yyyN|) w0onդ͠i@fă__<0Q~ZY2fΜϟ?XO֭3'jx @Z=]V|Aj,Sh0T1%#HAP:{WO١ Ur z[/ tEsVhNSa&@Yt wekLxOFt@A`14h{ŪJtgTWZ` K vy;ALzT饋u]TӟZ'^\>*"JvE sSDH'EvgM*oQ- fr-Z]v[yfC0޸a4i ܱ!5G5H@/4.`8z|T˫(J&sȔedTU\FI|PHU{ isdžmUUqV({1Cu?ZrVV4`Rl͖v|+}9Yxy4Rdٲu_TQ7j0a-[<7QۦXb.a7xv*>lwﶍ7"ΚUSK`<xuHzniZo=И"rK |*ֽx%Xv9؅Tɧ{tWX-| ?>"l?w TM'0m7)oI-)_~[ T/mV*'= >ZJAPS"t~c@ FC ߿Ù6BlSJRg0&Р*̫W SWJq,5VCc-,"FJKZ#UIoTpؘ7' @B^_/uψio\oGRs@)_j[489~;=`H.lkcoߨqc=f>7YZ?{2FNoay#uFzuBXT:?>9x?rցY{ `">3gȆtCj;`(͏$̓HV'{Eٓm ۼҦQ\>͜փ=Cdc~Rڃ˷uøh `jyFA ;ʆ \EźSAggB7?mJIhR`^d| 4v`=oYuZcR\g6EUH'zt ; `4w0os0xxV V~xN ;Em0R45B>:@:>ilZ %Xx6vX'4.Ξ|IWEP~?" ?9!hTBi.3 UZrذVm_|RUuٹs U"%yN@:'}K $vzX@~!!/6%@$[.T1 PG6c ۲em۶-Vm5<@F,}#G: B;v@?W/[`<xR't]|X)b/*T|֘K`<WY&bۢbOA7Jvβp)}6qT]"P\< !baӿf?^Pe\yxVɏVӟ6|Nnk/3i֨ݣ4\/rĜHdE嘇_أ~]/0Q6ml zmYҊWTdCs1h$Qtċ팘CeӒJR1|FHq:@  nx? /הQ Qs$ƈtƚ;O:TC Щl*g37U AKotOT͏}{XFq_HL<[0>{{D XVm&}]mel2XVlo'=bma!fw6V~dNl*U]6dҝ;IWMӫ,|ACkyqj h0TZZID"6j(8q۷***`߬TMytViJXѣ]Aw)>8$Ngx @Fl5w*j7*ys8@GP\!Dc:v'6[q-1_S|hN7-_}X.t6CoUo֜1a/$=A*@\s @WJ%5| 5RgJPx-[]ěXJYsRG* ?ʲ?Pm75FT: Hdʾu!D@GVz;%JaďݯKT[Pw$$>ayZig5#m~,2m0R;wrNҹgĹl'Ds{O/R︗$2sTk+ze.']8]c+6c/}r<(;k7unc{E{UY+WtPKqS1; ݢx@(xpN:/]<4X$oΰ.b_Fw!No'4U@KU!j%>g[/SB. 9 iaRŎ^tv"b ƃIFړoֺTXR֩{舵e^Hi5x:4 c S*T!' eixLevꮧ\oIm R?JⰫ`i&t v#B]fK"x7Q{k6uZ3#"ӥ` ݖ p6a}JZ] SخʦOascAzbIy`@W^<đ RҒo)a{ W׺j|9yE݈;X4C; Fq{t6flc^.v8hv_k Np݈h3?vs?."H m|w}u׋@B*1Om/ 1f,D={醖&^yMfqJ;j4xsAFe!j2]OλgҀ@Ԏ<;FjڃTӧORߑ6mSoMVvLmZ@pDK0a؞={8Sqjr+Y֥ qvbyh {j2؈'h4w-RPx@Px.r #['S=z&a?QnVdڛ34`8ns$i35FTcFNZ:M[kiCb\PW^1@<@"wL8̿o3*!Dh0[["xT%LG(ΈN8 ^{+3囏Ho?/]3ƉUHx2547՗iϤf+[cZ_>'2hSkKr [َ}rl'Љ ʾ3~=6 3X>^|Sy5Wȑ#N||֭zE,8pM:JJJfj/}q釤!vGh;:Q8)mMmɨ1e7G x w“H =2?HA:jO^,K):7(Hx#V4gLQiПf7/yABDC"瀎 @QAX\ş'o;M{+Λ~S{gbXYڂ1^󏧝'jT}zYi_a/4ESGH{Z7Voӽuڪt׉adX̓;kUUl(&߿>4Gu|tjj Azzs쥁hԹsg󔕕'Oy|hySk鮢=]y)>7tS󝟞x $AV]C{,@)+WYzPO$jh]70v6₈,XgZQߩ_2R+:CZA\&.6ȷ>uU! C ?HIJgga;&IXiO5BxהWC)Pxt`HZ Q&z~KŹSͨRa월0d eqFi`,>YsyctaA7[eosY"-9 ,J9,Km Yoޗ8`4~0qٶ{}['u^ayFJn g}ɃQ{]#1^ǚB.6ޔ +j|gyX\}^ǫ.4#NaJJ˧¨S?ҰOʏognv a9}c~"{˞*;x) u)@ 5m; jRVƘׯˁOR*|*J9nMWK^'v%{tŋ믿<}/x @=>^&~Hnվ#(W|J %%T'&E_o_7~#0WB%:`q@2U3n 4tn[j)UT5疩zCab}fK[5҂Hzji3ҍۦ].JqNg˾v3ОB)@gĪs,xX{'#Y̑wk ҄r_CGӕ m*qxz$,qEqM%:o~uZ|%ڿJF՘`}둨}鮨8~9apTTߍ{+Џ8g?R_~T("2:Ğ9%֥txNvWھ#J T]"6ydwiT,Uy@M[Z@͛74چIƍPc ]VbwM+AIo XWt\0*"> *-5Vi~f/w*+3뜡G1SXQq@?ԔuSf _@q{NlCJÊ!?:Ļ >eRoSW|z&_9k/4qP *x RhЋ_4#oy[,%8l7S ^1J &O o+տQ}8  RUzwKa;ŏ܊-Ŀ:Qfk:^ejMg9:T[ <@ a~BgZ=9P*//=ܹӎ;YvPmڵ6~1-;ѣG5k /`GmR÷<x @VzJOʺش1V ח3 ܃i>0bKמSTN$&T[AT IIh,xQ iJ`AOA6l'@JzyBhB?$;S QuRF8 Xԋ^RpG zľ  oK1&Hl |a>;6b͈fN0⏓P[U[ޥgчYB>e$N zZ:RxI#z_Rg(\%0V;.51bЅE@d/=tCX_M|]V/9olcP `=1f9 ) 鋙 iR3 f[m3N*=1ɹ:Cm2hil{-1 _c+@>^7[7wN[eCQ!I/r3ǶhwÕzׂsE|Dm)VR w}F`򔕕Yaaa g۶mV]] OYmڵbl_T0hР̻u=3zjuv/iuU`>`A:|X0Hk͘iUTT8P" qc`y=9f_mZ9s\=Sʝ}֩5\XHӵog֜ %t|RqZI~57=zt甒Sq:YޓT'im}4Ӊ xzl$6ӪEHy`fıGB <A4~CN3 z;{ cRY8`8EONs v+LcnHA!oINɿS3Wi]ӥe~aPM-DXy&qމS~x߰ci,vM,͹Fjgw.`֯e%6E0@ e˴P:d:'K?`=_kC$&rNaJm Ք>so1U`Rk/ mu(F#m"ТJw`hg\Qٜ2mSm֎#UwwRc߬i6uk}*,&%ql!-^vIc|6--C7r;5<'Ac1˔&߯G R33HvԎ}.H #[G(' 0 P;6]ƵEqa]K.%KXy#:eP.<6GJ>v8` k3ˆJ9?lOٚ-ZE>z|Pz`cQFp`zr[ * 0XdSϚ=2, 9~LFzAlR57eX{1 ϦO;&1 2q]W7IJXeIɃuP'*[v>XH[#!|yp HPL~PT@Ja.Oj3G]I=ߴwq o1.Qg^1duF',h`Du\"Zz/UiQAU0=t8"T]Ӊ#@{KkdzOv Tc_qޖ%ոyR`ݷΟP]2mܐ֜~cjt\+7}9.uꈦo5ߧ`0`PMh= 8i"yb>>ZX֫Q=j:/ ;vl[o5U#^|E[~=Uj\Oz ,@dO<3FmJ;;IHϓ%b?UT}氕fyڑMz 4@%] Es]KDCL9@9̤%7 N[9㴇ѿ/(m& ESF KJ#̈́Rt_kg:vM|G0L:X*]1H׭:`~)KZQN&itaS ㍠`][1`OH%C(K#VSXg"r`mKqk~jV/.y)3}`#vKd&eLI;%|zFɉx`fI{Hb7R5`ޟ32 CO{qw..:)=>e~S"=v(q^ص`lΜ9cݻw>}8&'@ūց9V-?[UowHE<|=쳶w^=K2?R۬@ <x @@#EQ9{wd7N'%Uh)o(8Uc=fوɳ2 ¶pmڥ<҅HvS݅2}DإP ȜQ63*l?{5% ..3Er~ fY'8 = rNwN}b B91=_+#F XaxO*&ƫXgYbxy J,eNy@T'h HIt\& {s{\cn{Smv3&7HĀygn1㻵nnT5>bi!>&{N r <я1 ,cU):Czy{㟔F_iWv8),1H_xyP@A=%qPik]k~Вzw|R*cYl߳ew\8Uhu@۩F])W6X-R1^ O8a۷o`\_FkI޽{gs=#*wcNZ`<x<ەjԱtn̰.6KO5֣@pD}$,Ko |afnUb?u~eeX oy i.Qx[D8ںb\RFr+|U J0a{0`O/v1V9=- VQ9qK-0!G]F 27 <%JLua)-*nQE#CZ 6.$@wRQC`GfRZ+~>sA}ӥW%caӛ2Ґl␰Kݛک:SW;_x, URi8 7S l8X*7@@ajN=_LQ^55TEmXgEF̳}c~ mzb J naS^Mh;.J6]/3؍eTW+Wਏ)ׯzk^bDi~iP񚾸b*&*մL_X I3MdJ+6 n-vB@6BMULoE`xj x=N{KR3aҸ& 1U?5}1B(}Պ P>zPu) 7곦y ;pœEN]] 4B<x @zJ6l͚Ž Qw] TH7[κكjm\X0wZ,]QVW}z{Hq3;-=oWlаD^^6=zO2\hVo_fdwFUʨJwPa}.멫SB BҭD9 (^V{Z^!<xZ > P w+ʵ  z?Qv\ ƨǞh _Q1T6f\{ JDZN3TY]A4Vo[~֟`tʄtlq.oia_6JKBICB@֧OI(|y(HGc ^j HI'xq˗2qltj7 \_rb⯪<X e$"m3/&}R^[WPU@>4|?|Q&-s4a`dpNh<:,-s Ĩ}']lN.Gɷ9󺐘X Acrq,đIL87\S1 mRG$F<#0?ΒحuZl0pLK~N@IDAT >[RkZ#v]c o{[5:VXe2D1(M5];?ZPX|+\#?_ܿxXkOQ_V"fVF8jU΅b, c}G1,矪w'ǹ9S[ص.bPTqq 0 FDIwhYj/]'KzHv\μ]vcPW1>ȦX{Lm|3rkȑ#38u2-54V <x @m~pt;GjsHۅ +dWZVfXwg\ iN9/₰Žr+9 `rcZ&j+`\PqIeU)#F1'&ҢZ*@cIoWO܏3yS-}زM4U1@+U 7k\,@(sEZv'%<~72 + ^U xeUzsbR]oꤎkTY ~Px\^jNUx@l`M2!2^TT2335.CFiy߉`/&jd)ӦMrӚ5kl…xZ><x @@\HזjOZF ጌ _' ~$c}FVmV󵖫œF\|(ojW!;Y^g+6 mY gn8 A`ޥHIJ?ŧ5u| %2 tޜ!/M^$^J]) ,0^j :89c`" n}?c7^eUE|OZ !e)8RkGK0d1D3*P&d?-럒vP4xF /X<{9m *NyoLǘ_Wv!t[/N, Fw@8i+4kTŔbaKtq9`ޮ^,a;cRua5{u-H1vD)p!n+m@ 3iFM1d0 EKrGo{Fx\˽w%ݜĪyqT+&*d PO{~EQcѹZHA3?ś^ 7#`wAKTV)@ί]K?@#byiNs6c` &IˢDu=ϝRgWvYe p/Uf1%Tt?o2r͐O {mƶuE5wolÔ"34EߎTd'`=6&.P&-qj4w-FFKrc1u]~.5U{J˽{!Yoq!Hvص~.TX 3D=ʏlt0'+d7Ǝ&0]mAw|VmZ`xM V;脋 |OϟWk ۡEh\ MիW6SϞ=)wkmmv-3]j,x @ 'Y|LHLαU64Jtr@SHMb*jQuA9/t)-PVWXVw'Efi4@o/`g<7ڤ`rULHB0HҚo{m BLxFIFŗ(@D|שM}垈] uSy@MPwLxSY1~P /I#lJScC >bePR#bnРNi;o#g<#H:'LPݔ7p;*z40^GoH{y} Yc@[$O׼c?x+\jxS#N1Tg0Rw 2E>OpF5.O=)2 ML-託+Ĵ֠LXt #-텛.U(+`@# ='/6@{[7YA1r"2w?7''`7żZU2jH\ałlC"6o6MfkQ[7C) 3}.= m 4Gy?w pyE!D93)֭2W}%O+(VE,{IoNan>@NvtpRĭ8sҧ=%وq]sx@i'-鹳;+,{H1hLp5 8> FVʗF-HG"fDZC{b!=G╭'v Tc t jgyS}}?(7bfhRl!aHfxM?)sҋҤ$k@#u)W~*//ƍg Np`F)`@&H2G\ WZefϞm6\7ollӋ.t6)H@5>&jAxP MO3LnN&ZC54MD5R/C"dM ̰Yf~ؤeDgQ]9nws]~iB.qqf*~@d]5:Z 'ʶAg*(/\e`"`rT14q|`Ēa0qNʠn4T3_,u[2Q^՛R`?aǂ*'VhʃG R)ϱ2a\սlkbρas*fJIm.\1-}Q1}-Zlbc 8JSڷ1/NrDNTH҂%S[--1~㾮r){w_`U+`y,)7/oOu H Щ-p`?'Nny trP/!^2T(/< ]uYs6Oҵh%uQOk*=[,vEngORb?e+|Ќ5JX!gp7ֶZ0GISayG͘1c4X_9pat/@ҽH5YH@bj`O g4ͮ5ep/U0)4'We6sb?-i DogD:'SLjP_k2FcVvT `ΰ!Hd8[Aް\0oy篧ZcpzsNY8w+ `0vz۔ 2 Z :|N<{DgRLg? 1gNY u-V}=w/3`v 6sbZ_ ,' |s(Wo< j4fЎ0[$ )hX@'Yl7UNؗ0zڵ`rrףu&v<8ll/eb<#Sr3]k}1mAa2XFݦӁ=KA;ʤiQCX_'׻BcC Rt #?φk4D c?Qnd XbdiL ON.xff99wFR3DHW:PtѣSy3tP C'\N:6ߓ&%YH@5g5 џJ'VS@4OF|*>ӰsRTS#S<2KgtAn/HC]\>e!S;'VwṓO je/+F=5M)WO3y001(?O@.k)[~żrW#SN|J#j{ Qʐʅ![ TW@Y1ig]/uEQ` 1p G@Xc"WT',kMRQ0TO(k1`B|n`n؞}y2YF= +@0cdJCpO`3Q *l7O(5obr0eq;B|bS1w>WS,(Snl~.^{bmu-֣LYc &.Fڭ{mmkGk3l2@45+@|%7<ЪnN}gnŢUqu}uo&hIxv^xzwF\FENHJT.v0&|LpDE ;T9y҃Ү4Q֧<#-3gNhٲefŴz7˗)җ^.)H@5^8fA'pIpvoVb:ET_-I =LWuE>)Q ;+*jMU3d _,N1;0{;萬z;N.Sx,bA "2ź(PL7[vFY\*c0T +"3Gl<) =fZU_ ŷ~;&˗K@9#y!_NQ r̈́wp X`FSܿr;&[Ԯ4Ʊu>W1Xd@ąB25bc19WۿmwsLsJpXt`+ \u bsvhibtMJS};Z?鼂;+Lxq)AR5@ u[qMp+--0LH>돏D|}@}XNqmư`QB> # Ypqq 1 "robx, w^)%pq_;Ct'ktm̻vk!.]sUؔvUbIG3zB0qsܰ񹗴iiuD,\z!2nZ32žN3NR1"!.]b^\> =g+'q0y¸ޔ1 _r/+;j=b?iڈ#T z[y\s2]YQe}@ĕLYNPz\5eg6 |xJ3EC~rkA-8iaJ4i`bWUMc"[E\ˊ:vCcRͻUKJJl!C4,ww.HJ?h>CM5d $ko|l.ݧz3$ÌҊԨAŀUSYU nά^'X;}Mb/\5uMVD_K0AY1lrerH| f;gw~ [S}Jy/ L\Dp +}׸wL a/h/0f/Tm]oPUCPTC ?C((WHh?nv+G<;<~_A;{ظ[lG]NVF-?`؂_(F;[ɽD}۠p#0YN \k$Ԟx ՗ xm P ɨO 's6 I,:ׯnɃ~.'6K՘wߺ/q$^6IwL܀e*i2 yp`262s>ӕWꙅ BMVaGvC_zR?C M ERQ׹MZܹ:h4i͙e\3/b?յI{@ՀZ!%& |Ә1cT+ŋ0q z >C1:ZJt޼y6,.Ld[f9|޺}G Ҥ$k YH@D\>,-Pbռ,  lֿܱw:T=0?N۳X減h_efO} 0JX ׀qOqA_C0Z RLO~pseZ`h9EXI˧68|\ F odG}3/+g fWF Z#ӕ 3mr;x Dc?1cl8`fpcKݻ<0hG=]7FŖyMv:ނ$/вp86Zm/"t=s)]q/o]i4xB"X}U -@{N!n(bwŖA,T=ب0!ID0$dq@ںF5b'3,VǤa:1܏ZUZT"wkSt֤܍5x :Ay2j޼ 6]zzf_8I%? pLSrrJ3c >x̙3\;Ui]Rd15d k5_37p OPjB/˥nʸ -j*{͵u P5E8:8_d^U&xA7FvG_a `{q#CZ5KcBj?e9̣*e-6hzB@q1u1 o&*?Ħ=4ˆ!O6/FR'Fk I <J$1T̕$7߻cRek1Ybg3x1BFgqmԽyz֎gPEN`]Y`o(6EM%v$ڻw~\OEW>1/_zb-f"Ca~Ws5q'=q{qE|3 rO(7ec=z H;RgSҦ[d $k Y֌C#,VLΕ.>"w^2&91 y)23W}\c`C!jyYAzQ9|R%[nVʹU"3 lM0o<KZ!8\N5Fʅ -!}&K lWõ PWbNBU~A~Aj<ٚ_`2pRK}o vuaDsmQW /f qHih1 `y()3j prxx=B?ຶ ,|KY29huAf2)01? fWhu?l`ȹ&OJrIɸnڊOƘB_O裓J۠v׵L?0=VjSzS\G짶 eΛu#>_8aX.)z<,g@Z(>?v[؏2!wGuYHMa2ẑi`[f sL3zPCŜZ{~j`aCoHp)B̺u,hpCX](-b[I`}_$k Y\<7x%~wa[|G?wt|+8&P(+D`gLxK3>:Kyuse3faq3 >lhvcV)6Ko\'F ~8#W.W,2r= 4eҢ#'s;>@1(Wklj5~-_R<+nNbNJYqB3Gu'Us͛[n ȒȡإŤdy#oYŭR?6vTxgY%`ԉڸ?~" J)3:↻ڎf 0k|h ?T׮u W[ pi\aƽx)0R: }Nx[B}rmEŋ xQSQ뭲~E'߈:>1}'%#sƅd'n׽UF(ҷI{ iImڧu_ Nۥ@ J }>hRH3;w}_T1\nYk/p;#>Sjam#i/zAՖjN 5MT,Cu^敆u<(ոqrEx=X|*?ά߫{CLln)V{,؎%Eie%J@zTd P <ZI'Hgdr{!2i$|rs9ztEi?>t\G-羫ѣ٥ߏ7zsR5nQbh) & m= e[7X(}*Um 2989m9B((Ae`;g;esS'cU sםpæݱۺr߸wxͿO[﹞n.:=7} YK3aft_ǁ$04?_[kjr >wѬΜj3Is:S4rZG2^i4'纮ӧk 7R{<0d>L/La05d >Q|#6w c_[I 8_(v {v<6K&L+ƇeQ' ͌AZ'<gfhs{d^ƋB5bL[}ޓk=r$pzg1@=e br gAŝ2ݟ+`iHrEC#f sL58cKSgnؽ-uҩQW^5۷oJKK-P/'~7M~DOzDz7H 1Z)%%%6X:*++3N"k_Qfo[,d $k &{qctkx`y֚Ɔ 1oiz|B |oڱC/n&t ȉ4۰gwi8Ml5i%cuvq*]P&yDM!M2 vE]0l*3k3Ihٲ {Ҽ||U\\_UQY(ۼ񖩩7wSNhb@ 3ͳtaOY},mN0pT}/(VY&2i%bB.zq<3@8a\01x&ф}p39j4X W\[8[8/pUV&c&^rsϧXV'g5Zm+ۑ5Tuxz϶nbG?h)a|jQ/K_,pOIϯMmsYR>ӏ?"dCX`Nh<} H^0;;r pb2wU`;iniGkv~u2"C$@0m>\ :=ϛ8z1qI"XYe=3rfGz8d!2W%r9.hs :__Aϝal-W' Kaܐ&%Y l^Η>Fֻ{͛7Çq#v2ƱjO{&=+;L4=0j(h}jxn!-dׯ%b?VnU`EMff*(妬5 ǞF0s[e[`D,'bm(1oV4LOe^<48;/~^]\i0(MmvǴg쪰-ÆW}zH`.Ugreb=fhN! b[Ҋ~[9ێ%1HSbg'c^|hNX15 ڐ< fb(.C>[`ZMSn*_z$bN]1>&U.{֓BO6Z^U9^F=3W*a7OĐ VB!y gF3OTݑS39LC)&hP33[5TٱrPbōQ'=5pLziR5jNOtty3~xpB}-X)8yt]i vw2NBpWYGh;(,HnbiґaAR'A9w'Aw'Cwnb^iB%3NߋC#ҫRIj`X@VcP 0mPT=;l8;zV5hjC# |tT3|HHk3ުE\zٱ!\Sc kDLLf6j66{UhFfFgגE˄fevlupZג=-*0ݢ鰚]R@0?~K bc djOhGKT&\`<!F;Ng'.Я=0R%1;Ԧɵduw`;Sl+;f M?^v}feR2rVX&)ܐ5|{kz hHxf 5*8vK76vmvi['<<@@^~y6 ẨukO=4'dݹi2D[lKhr:>}m/'vGkNp8ͦJcXzo,my=&=XGLٹjJx\.HfOJ7/WX8\Y) Þ%nZoHH?%SӖ-[,C\tROf֭LbJ?,=,"/$XZ>3|owT$-nRޣR&@&LhF|F7nUDg6QaLaR{OO)Xd9"KRGwp0`ŮhTSX'.%N1^k%xQcvP;7xj^G 'cݥ|RA@cvv;/AA6? ~0|^o{bOi ׏/ gm(M_}2"OȂ+y:rp^@G6,kH3wF3ba˰N$&9ȸ+mRQ! vnJ$^=6g T dqC F-t0]#܍!]3&ڞ !"QFžݍ1߽c5ex-Xf0:p&fiic%:Mt<~yNhV`v :+1IIրuLl1b!7F+P9'N 7esB ӥdN8jŊٳgNe擴@IDAT&/lN< {Ug_E`l%aIJ]k_>&].V*%"͑h&eedDwD5 ꡓ.&MO Li(YZHM 7S,q} ֝11}wA{6J +[}z7?xw6* ¸?`߈Zpds)4(b߷xO,i qM!,E'9e. Jx;:,;R'2$KrYA<}&6ܝ!otLCv]hba 1>/uHjY|񚞩:C_j >hʯ2=Ze3J@I/}pb|͚fƳ9y)HJ|5]RM9fڴiƱҬ݁̚5k^e?1iHN聑#GZB~"ӥKL]]g>ޖ4^Iӥ val&+1#77]E: *8[F}Nީ/YC{oȉ82u9NgT v<'iwW3Z>;jʪB M( /H=Ǥ5@G3bW m[)1W{{\Z7gA)R-(ɇp@ TѹX^Wx߉sL24$?bFȦ(Nԗef=pW毨Op7c &k0fUs35gk~n'kgKd}iSۦU63OTi gY_0Cg곐N.r_V71bxdb{< @ €)%ar L`LPjIҬtu$5+=w?%Kkᤐ-Q8ZZ@ֿ?">q~@&0?@'Wawlyw>AZ 4cmhԞk qbӰ l`=S=a֟,'= n*Q0% 7DIJy ]URZio ;Ƭ3⟉H|g\&'-U^,7"y}}) ׻A`dm 1֐ >| r ǽtKZ0eL-.pd& tUnN ֝۩+vYA@@kGbL:uxƖo^)e?g JV ~lx.)PfR1 5gM`WI14b FY+].]VSSc9b l}|,Y~/fi/͠te~7`kxuKn3^G}]\Hg6pFE6&}DL"OLA 0Xl^9[5/ Er4eVl$sNa_݈FTe;iͽBlJx$ M+]iOzsVm^Lz&R@RWM]V%Rk7 )aZWcM OqG-yǷ}Zy&΍w9`*ūbHi1FJ8&C`ts,3D >~ 89 Ӝw W%s&;umc _[_^vՉ< kg'0rعZ*)\633*uuڄs<6bH:Rc.]3U::vvow ݼSUb8(n^4'?,w_cu;g0>{ i X!LӗĂA%u;, `d"CYboX+?1eM .fݭG?S Nm' PO"/uJw-ܰu7befдg(dSO+&16Kb?kLbvi;Ob]O> dP&\ј]zgBZ|w8C݋q軉,)(O^>^.FA:5}L0 pQ+EA_Kq'ê#̸KrG'TG݂1 =O_V﹦ɗd ieSk .vJKK '\ c3?~,r })=-5y䔕+W$,n.I3abVi64)?dJ8)Ը YzZfy 1j$k23j{<Ź7J5Pٵgr}TQܑ/..;#GR2}E 2&Cib$ d/]XEytv^2X[ەwySe)cm]ؓS,|)j5(eAP)ɨji S4$\)nA/i+s;|<:LJ{5J*Jzj3ͲVLiy㠳nև dpO LQzS|{3lc&%CP'(2uua#sY`g/@b| Ra[ DLw FƄc b&yk8 `( X!H(~R`$za,>xVK2@Kp{Oܸ/ϔ:~N2 uE\{ \ 8_e/?ReϴG#f=B[b4}ҷ~ l ^%` Nk)`07fal?o'.+>qǾxࡿ0g`?⢛(M9ڑ;;0gmRb\D":bĽ /=lxb!xvp/xVr_ګg;kwνWl-(DuszYETJT3ndJ b8dY4@<ޕ&%Y5 \;X%;W)))YЌ euise4i"z |^:Ndڽr /؀*m󲴧OK!pzJD:Q:TK]jJJJxȐI&y'ճ'+1o2 ͜zS*VIQv\R K:e22PPSx3 f 2#V$j}\%a^vcDI|NJ[6s&gIFy TxL9vƂI 1G >cE8PnWsڴ2`X2qTkb)TW?0NTW; D:߂⧁,gbh FwtT9uҏK̾ytq#aj r5!Lnva{=~2`tsHxo_1~[_K7]njcR׬mQ3BP@XKL #6!Vh{^滠>xA6BXw xz{$_<_̶­W%˧D(<B52IQ3g|PQz,y,^0;^f93TRۖNO dLF~}VJnWZT-l'No3rXVwl|d jb}46md F1Nµ 6ji_hH$ 5Or]~R=Rp="y: &W_OBa!p5{yf)fDh3lpyY׺RB׫3͕֙=LBJLYt~rq`mTEô}>Ŭ.E˩ǥJ+}Oj.&k CodSɮ>C\p ;#(tZەXSOz3* uBu}##bsVbkbSyqsf]tLx盟(XysX* i!6A=[_Y8B$[( ?@B:@SNkk)f@gFl"RNc^e#5w:~8Rcp=Nێ(@'hv QDZkw==$@Z0+'qu@5ƾ{΂!/a\|`xl1W?yPg*u e:Z0fr gLyeET)wK0`?Of6yҷ:r68+~A:C zJs1v2oIٞ .eio Xip@O׮]3.\ 8$'HII ^$ W4_ C|J)V|̑<陣nP a:SPo*<'=+Zxx7ffbtd'^7Qĵ yifg% %jϤIOJ ՛I ^Qҁl}r= ,y'<#jTo 6c t w^Eiʔ)6`74ߖwQR=1ELwh-'vn!B|>s~e}s+4sBWk7}Uc[M\\i^XTˍ&yFڝP,![0vuS Ed @8 y{d7΃Q8M̄b,M  VʇzZ9$6 w`;p:`c,2 }oƈC$1.F^Pm2[xQ0b4ô\Tgs䠂uK1X=vG7M2z@x!7)&N`8}֣/_ߡXlŘYo)LJ_ϽJA T7Aw{HM ۺ{W=1ih#X8yLJlFYZ񺀪Xap/DZc6 +ѳ6 #=N҉:cՍu=J9ѹxRۙG.*κ2wbS}ǽI$xcJ}:rF7kfٴŒI @2jcn5Ҧ/PMҗoy  &͡Cŋ5ZҵW)ChjQQQxOr47oޤ|\aiӒ޵x)E(n`'e!I+MӔ*I41"=#ڈ9ʉCJ |eQezԼ"6Js߁ WpJ6fcAMO7;B\6ЮfKKOHXz^IOPC 3B&O Blu jIdt-*GAwO|_{N֋9: q9UXao K(0?~1v?!#uV⾴\OW'CJu?68 ジ^b]hęlu '(Wbw*gU= >~U&clc{]1=h~#zea^mKN@&Ż|GYi[ W 3P_@[w='pM]=^25 8`eۦ1E~;:gm_{/}]ƴbH͉H4a]۷'c,g$kVE5,R̠!k-eܦs3 ']X@b,jH"5T:A\!)BIK`ڵ2p#̙3O滀c>vUio ?@)Xe"8.12AeIqpaلgO(HxjPeih. vSF0M/v&ß)>tGtP=HRٳ&_&"=g͗R] 70nڜ(}L/Icit/Ęq8xʼ¥TdrKwŗGڱE lQ.]j`\T\رc }v @5Jhim aSܢ[s?&E5DmmEOw1? @OU=Zi5ƥ#z޿ ˂O|Nϱ_+ECft\̅ |z Y8ٵX'rI򋋗۠;#jE|N XTtXN`xWg0Έq{_p-XqAǾ4%Q~SҳahL$Po0b]ӲĢ-hn 'ȞXנ p4M̱A[or8QG4Zv6Ǻ!xHz' YPҿ{nU\w"uwiQ2+er!S' W)2G f87`*  ك=H|xOxqO=Ɛl-`GF9,X'fܰẨ1cOJaq"QIMWB]WRl/ubyygf,"$4[mn]gӗ@U[ep79>UQK#}PLn:)s UUUf͖[7O0pc?-oJߒ@0  CxOI2b25tzk[F9&3HYXuCĬ&e65jnpsC{AzJ)bԋX-V- =u8J@GڟPkNטc7jµ@KW6i߭d smOZcA c'ρNN9bW658rH3}t ; VÎO_c^+Қ$6`ueFܳ]!ͭiPTaf*h( Tsz9՘S,2۴YX+dꘞe}~X)KF3ݵ_K12V$=| 2^qMØqAP/l}ܶ^Vv65ET@'`b:a<&:0b'\=J ky Z8>8[D=& euL].6œ,=\k1Sq@î !}@X2z`Zq?g8q?=PP˲Z:J^q-d"#;{]~[5 .go9\-P˷C].x HP ;Jsw 5Y P?etXP~\'<^wW8wB* K1xe,/!CqhO$^ۯnX>G $w~JIU,}?17N[I,$)Pzxcj5VΑ m)UK>' MJbk2rI-ed2``xM0&i{\02qsaBaZ&a/&)ya W۝;$FJrp 0~y$cKC(V:Y3zˮ<~c,޾߱=V~N8&N ) ,)NG|)^ Bbf̂Ө@a?00750 -vQF'3btG1*>*&#C t_$% -pIIp6od2AJu[ ?U75;hU+K졳rg%K}P r"_Tk^hv!0{68{[XӦi puo|Tu_c㚹ckL˯+6gW+>c4ALJmW=`T(ޖ]nMl:8,kkgiK7>7;>avϩCT~Z*css%Vh8 hX(ծ{ 7SR5`kOrqeZ6.mYG6Æ Am+"7MCT) .i;3m91G,^dދF7ߴ)Ye 䤏5Cs3r0yi3MZx8Nt~zM..1fGLLS;/[?W==! |1OȋZi/W6cFIKINKYjҽlH 3#Ũ>e |Z<5C6:qPX> knQ-BE5WKP@3рȃ.sacn,dkfpo"*röVyr@/?&M +l &0r [݄.S9:Ui\133^[L2SQKW^7E(OGl-m-Z4E`H ` + :PnR>W{0e0 '\{7: Ew7-\p%Շ6;}߅IyWp=µrbp;P&bWSq[oi]t3b`u}֘z}>r/`9ݧ̂\{,H~/5ؠܠxP=~;-qd_!UA7pݲ#+B[䁇=؏J8DFIh+^y* 7^ 5w\ e `\~ <>) b 4U\a3e+uQR*Cqb|xsvj\$( x!;n_tsm؁S', -{,F`t3T:S}h] K`If #j? VmgUPr gQ̥ï4c=Zm*,,fbRq\f*ҹRHx5f[קd``mڴfQmBlׯҶ˛۬מb,8O )ܥKx%I)ĜV*iՍBYŸ(ݔnԹݳ*CHL޼b1>PȤP6Q#Jg?Fi\._6nե8&]$Eҍʛ'+V=Շ;{k+ 1|XOd~Ɋq2eu#ӧ->mڴfa "Y$ iPцE3 L's{^6,sBYGUk,TPXVU\歺ZQӼ8TWېiCPSI'M;uwʨ0pF}vixu )gRڭi9Cgr0O,'Ƣ'4bLeYϯmQf%ʌa>Җ1oT04*;e{Ѫ{$E1`Ll 8 ɗZH— =B0qeYUl޻fgvfjW&iߞ3wn9s=E'lȴw'럗f HI}B/wa?J ɜqV6Sj;Q# 7DFII"ML+DJ!5mH/b0H|4X|bE޶pa=._4 \ˆ1AՑ 1ekSz2E4"I@(e2 qD͹?u{87ׁ<#K=6U.U7Y m.=D)uL`2".e,wxSnomXmN&:by8d~߄Zi:_Wk޾KCC6`z°lk1;_>rk48s_bW~Vcxw~੘{Ko&šiWhokr?":]q[vkb/ 8j[mi<ξaU)00F-&%V̱`8B,pVsXF`}-OaV?Q_F( WYV"&[4C$v¨W `zm[X!PzM":qԦ} PKRi: a7xñxGl޼](zyJ7+mS l9s˱2… ?Kf(m#)rEk>]䇠 وQJXRi?|Ql6O+ʶ۪uiuQ@)=C#ܘS|i_ɌkfMKf{gڄKڙ齷zw<4}w o;1S _\aY/Pa5ٳ']SwD[?~LP 3b"kVkN\+΍QJb7k8K/oH\AM4\UF֎!caV autBZˑEScKdՕ z xe2$e)ԑmg*nX4è/Xiy>Tm;Gl8m_X]7+[n{G_;-w|bZ[/]ˤbt,I0-n7łIib 9d :}׼'V"p-ierFW=`mzet_(9Dq I~cR=~X@-om?:Y, ڞ~`zfVi٪sI;l/7q0-p3|M9029iaPQ9&ui*o`ԏV}Joӱ8I`T!b6~5FkDw+JPf)R982E)`|ZjgYɉr^dʍ>j@ޑˌ6rH> )-WtX)eHT4*<'СC 2[ @ii@m{J]aS?0n>˚aCV(Say$i^u[0 6XmS2s­dF ec^ ?hO=B_ܥHsJ0hMPit Ip­(P0r"z#Xy IWm.PR<3^:#v=N n_qJs wDd'kȧq~e5Q,'cYvȱճN,OfVrK+//cb<9|̪0ndn]7 L&Vw|m b6<'Kߚ˽o}m[1?$9X r}d;M Iק3I.ghͮ^keyd|U{ ](I6ً][>x_̹y2eP=jvhggmt Fo}%¯4ùW>:'XNz(]X/75Dk4pt"3*7'25Bb1]N'/^L8uiGH›FW}g{~hzoخ┕۠AO_@/gλ˄Czx`^=5'#v,uvJ+J>OЎ o3ckKΕˍy<9 I=Ϩ8-姄mw/hs@(MAaz!pbE^U ]ڴiSt$>>P}NiCnZq`en`qym&AīsCFM>[Y"^R8: >19.^xt^I#<.qNwSd{o}fsnRb)@ 47l{nB`@Ck74ށΙa:b7 ʶb]-sg/;TV~u+{{KlX_G:A9p4Ic\LD_k b6z6$[$(+q4O0x@?оs T/nL|Vt#Ok8;.^Q:įq&\D?kϽ`X$b:8!g. y@胚j,P9~Y9.yd2Pl:4_mW!qXkkG\49i]Nà3|H٫<4cݵPy6CzkBxib $g_%2>u|Z<8Oq&2r^kwYq;5UCψK)Z+hD}cK4WELYsm1[Prk7p]jT*R/vQnBe/s[k*@C<扙`#aiߓ}e% 26os(1)[lT Ti `9͚5˖.]6g?~&6%OE).SҭJW褥3^<'t9)-=,J'~- *@Ek|NR 3 Fr Zy"bGJ#aiBEzҷ@H٥%@cjzw~@omL"S< @ 3̶|&} 7 f=ۺꠥF.b'K&3'v+MWzL)2k5IrPnw,ʑyLڞe559u`rk|MAjhfrM]pHQ5>WMwaJws P>ȿg`߆߇HWlv[갑uns%k;mV M3rD1nt9rPϲ8٩]?qw\n. oY-@ o0$"O=%*7F0@ c",WvQMEV1ƉefoLkָK7aK[=MѿzruҀg =86-&VOݛ=AgRhUۢ&l#ZW~Wm:st`%a6q1g'8$ wrR#z0d7 zꚵ?=rϮ֩q{BLxǥV ԭwErs҃Ӕ=Z>g Sjµ|Ũy,1I#~ 1sVs vZt7/{9_m2tYPzjs1M,'~-Vhw[ﰉSZ~ Lɍ[j靧[ QQSvۿ{۹ݎ9ls",ifN?>4©ٶewbKJ !e K J6ZPi̘1`ۿ?" W^UAު9qJjl(SbFJe'M$)܆$/1k2 aʽsTbDF+y9|b{7j36J FM{$іD]\;燍@Tn7+|: rڤ tD18!>o;j&%Z~g5bNDzpo20aT.Ko]:rɎy5DYu$ݓDs.PO^'>/q AUѝ٢=ljv>dn[(p͕G~GNWDv\:ڸ{O te:m2$' 81e:[-80 -`mWOܷ?y(gmW>kaM$gu)ntD{޶lXk?7mM|]oFyӄ؃3e( 8 UV-)ɊJ I 0\D}Yݻ|Kܼy(n:d.ݭZnWbǕV.9Jnجg#j||0 %p CNg}`Id+=e>~}.{ F) ۳pǻI:+Ov>K]DmJPZx WiisJ )bLN/yT+958aٝvFw NʹH^N5EXƣҌ+=L? @f#WX)PsN\{ɭi8nvjlsZȯk/tDwٲYk LC>_Roﮱ]vpD94Qļvfm?Ѿ=;A"I'd,yl՛u"ʖh)«DŚbx7Y(z:AK :̲pw 8PY-"}uuSݒIߵeP crیzNcŊQc:1QڷݏHZ T}_<]A'2 ޭ>rߧJs|y-{h7'0PxnD(ۋF=kFC {튨,lu`M6|@D:T6g-1'].?lM/MbKjs\=;gq?`oT%+m 8O02;I;Vvn5Wic6a4[~=Tϓ&&T^UG-wIW6 `ĶϐDAM~efeIFC+aBbAgA=5lїJW JS9rm۶&ODF鴟|W\\OޢR5Qs+%^=,xVVSu5*a11 .hT<ڷ>[/9;Hw??Ky].%&y҄"? TD;ss?Va+aeV)(Wm5ԧl@ҹtOB 2?G/Z^뫑+~sO/n3Q+J H:?0de۩1S  .O-MisԜ3RcիxKno :)&jϸ֘y1Xz]jXKwS$#uk]j@pA׈5M." ?sL2ɯߘx!Fwj8&*8yå , pI޺ (1aѝ5)GHiu ;xt-BrcjS}>xW-&藻E܆IhA-q9_JW  6]H<wj:m[6wgDiQ=yzI2Xh9 D{}X Mja9=Yf;Lj=vDZU}OL4ZƵ#d9S0Č`(7|9.62`yKQ+QV7Kg ]So'  9 3=1֊v6c`ݣDP60.Ӟq~@ץE(z;I"'f' 0B[o5S'T-]JoQNnxu咲~fjۧyjznIߓsr_;]y'(UEmb;؊{_#!` ]]jo֪{_u@cL{hE  Qԫ PU@}őSzUz/jJDCi„ "e:Ѡ|''Vʮ؃%칓5EG nT/.N@'7tt}Z⿩J`^W[cwWXEC~gZMJ5|7xRP',PNjDݺN+,-Mm.i!{cSButh .5{{4WQ^\2FXm;t_4;D?7At(t9܁-Ԗe6ttgoJIùЬٮh/TIDP~RO-3rQd(bͿ[ W Y {=h@5!g4A"޺\C#g%1{(h1z .(RDyR7I>ۇ5p@ <Ö/\J1# fPoO! jI>=}=#k:k~rcBչ}"lUcsԻGmԍ'iJrbLwl1kݶ8SR`+:!oȾmf 6MHĚ-}kOY%S4E,C -ƞtN͚LC<d.~%I&^Latp7y'‚o[v;c+oXh3opݤ{ l}`ц(0D׉-=w3ڝ^ktG^+YYm[6=ѦnGݰѺMhkگWF6HD`.%s&. oTdەq%Jo\*;fg ;CZ-@k8>Uibz; !-shwjG~>_Eok][PчVuz67" (6ret C~@8}TR9%@=Qc#f+& 짬,gy~@%H1P2mp-68vٍ8\" %V\U/Jm̘1l2':ԦM UA$˕FTz:8j7 q-cm W0?UOY(4;0drV䊧c:~JT,S)K`.A@xZl1IKq"E5" 'u'RSNj۲K. JOsC`j ]Q~Vmv5Q;,Ӧ`wZqY"eb?=Krs+. 0[JNˍNbm]6`0!5&\x1Fx쫝6AM:Ӝw75I|Fl+p k 1qTnnFl?H mEx׻ h@c/j" C3:i&D=r(Ֆ}sud2}q-ia{poqL H(dܻo=~qPwۡrmm:S( gu{b\V5O^jD9h]Ho13A=[Ҭ3=1hͧ擁Hl ;.^ &{|BS&gOuhLf30.'ew3:Uu^;W^񒚈4!4m}={!Că~{F8s[_=; Ev^7 ]mYZȨj 3Jk4\%S+R# PLEd=$i3-iJ`A$Vx˚pX]~Cc 'ld^ncmܸPš.M+}QFKgc [-Z!8 3e=^E6IϹKV%F(ݦtR9%ؾ(QRցmީv3wʥSO )*f&=[KJ5/ntH@Sv>q+~@Oy8j?~brxvb KNs A$5Όϒ^}3B _`X]6pPNIo <GHq{4xc EDk+{oq.w>ʑ7ѱ)b\[cY%#B{o3b1#" 1yx.?r.:RC*EԄ&p^2{T@ZS(2Ͽ7Xd/әADߙnD wb?mL\zJx|GE2LMjh@yV_[bӹ]ixc5dk0Qn`j„g<%,@,aϙfDI! $@{}'\N}3>gj]_U֙APmRct &[E+9YۉH[Sf̶?6jKVbWjG=q~َu8a]7ۊyLܯzEuowq+dԊT .I\E=z[Ɲ8qQ )HT<i}[Mqb3Ji6g|\/cVYceV5H tZO}K{6,|*$8ѧa*4ʗBy /" 04Jsަ4O ;}O%0^k[I&fƏ*adr\CLz^X_ae &Ƨɴ9tH=m2yaO);h]<&NWfO*l{ӁCHйe=ƿ8C@V|F,1_/o,jp;$wF`b%a/ ,ץZfWXL o/rO˝v )Ēis𦽘<&j݈˯K'HSh6 1.|=aoQQkcTo=Hqj=m0;k;ﷅg Zw(@/: fӧT} L߿VirZOfx~:WL.uvjlOg+B:)N1׿eVavj(zd;ʶ^_^}9r[Cp^gEsdRD IZ,:qgT!.n[nuZOD8qsw4iyJee!Z qI9׾DuL8&y :k(}1 e['mN eȳ3y!D'Rz7~QqJSp#MƧo*Q uqDf;tBa ge\`g7ĹzǜI Z>7ۦ=ZW֎m&j{" #NOG.IV0[o˭)x㌻ ZL=aEbhDt!= ƸqyNW+894hbxz.!م҈TºT( oS!Vvbݻ'B( _~}f܎F e1"'3N5.G= ۴݇0vH3'QĬd'&ڟuv¶ptP^zԾzC MO偀7.Oq?ʼmz 3Hq~[>:Ͽ?cavˌ7`Zd@WFEy]-[D?C5O2p[}oΈp'3:НthttB-A:nf m;M4m@6m47ouDLJe\p"2.¶Ja[3z>X=A~1'3wPYtX,PzxDa~|3,V]pƴ1Q7Yb\3Q+:!4؛Z n4RY%үRGZG /2[:F>._wS%Љ\Խ \/맇 )V_xZ7VS~upf/>/;)DZz([W}3'oöo//hw.ηsrt;^$3&ezo[q;*^u֔]K%+( C4R%.%>^zqG(V (7^_f.FVQ{ȱOD6_fܹiILzQ:#+h="{rkSa/!Oh:,{-Jj4og2&wژe7*ݣT MZF۱)l ݢęq}8b6K5<ՇZln˧w~"ܼ,f#6]?;XQ~!{jZ%+*~5- ٽO) > p~{xv@6Mӓ/03F6kzu78TnYo} R2&OS/Co3 pD.ʗmm˷3mS1\z9昽+Yv5י}png/l~P jg}.(q؂ä%m$cKaEb}쾠@+%33ƤVQqa)po[ۇ ;'3XSSG@җ3@eεSιhOשqk蕸բE٠mmxF¡gm?S1  i΢/-^~X<ث+w@d-׋bugz7:lC4O=׻vԁyPiöa+..f 4&O,VbX rT}lqscѨ]%:AXO8Lu34T;K즲+jLKG' sm֠L_^w(ϔJiKtQU3ɼ:O6h#F ;x 7_1lcݾ0׽qg ʋ~ +}Gkd>n_hyc<0dT[E-;}:1ABSeu syw)ܣ/{%\r@qrm ;& 6w:bTwԐ !Fb_% w?L/D4F`'5Cz`j*vj1Qϗ}$ 7ix=r[Ёhf;DQc(H-o_& ctvO z+>WT 76XPó-O|K6o ޓ}RW\o}ݶoڨ7J<`/p/:qˮ*;*bKYǝh zHͫ:xjp1һ4j(S:@SO gx. SUwwX:Qu6uT]ECg*?kưO6Kx* ngeo[1AXg:s97|N0ؠ1Dy,IEa+Ѹ9mୠDuTL(N1bT=iu̙;%EvsF[I%@?q#)wNg+8ܽ8OxQmWAǓcՐU= ǟQnOVm4K1v'jI"EңŠ5AeDh. g.6$t% ;d_X&=? 4!%?aXdH ;>_PX.P_*jxOHt}Z lt9 Kf(~Οput4 w賟٪m-N}wd;s?$꟟weoVDɳ-]c-k[SJtp]>=00zSO<ۭ1=6e,},zڲasnbw .$6R'V>w3&dEs˔xcT $*^`~\JyY7ZFΙdڲe]xсMM4 _q{K3wmA|Y . ]oHEK+0<59|ɲ;'yG H;R -V[J+ U#4m:Za&6?`Sݯsy~RVx6qa 9]ogw-DZDJ\@IDAT:%7=mXBh&F{SV!OG&(&smDkkm%7&XbK% qϤ'_WD M)wDMO]ףcڸ6w?fnY޵L+Vu{-'6@[<흣;C# 1f.g0i _I+5׹6әԞ;Cv~wB}mIH6~l)9"*y=蘋WҟynwWF=kޟL?䁺q)bŇ}/JnsYLgmmixOw̉=a%Ŭ-s!q&Fe!h3L.RgJ`c_kFIÕ&MR%+v+=Ӡa^: ~$""ݻ]T:Ǐw6P9c5'!-w~XX̡Q.{^܀6 UKЧ^MQi8tl}nQ=<9Wyj+M 4WCJWJ0)u鮭S֑pj}xad9-Rku}_hl[֟,`rc I%3rBZ۰clτ.]kAnxlDl&}0z n3bw묠p|ĺ &ѹѤ!ϰ"\1dqnn;ʣbl9zGҾ/i}X!"=0;EeCA{HQY?gZI1 k ͯ}׿p+l]hM)`aF/%op4|g)̸pt:vڨ'?~(K[z4H.ZW QŷғNx:VӇv}kqMO޵>r̞B~ۄa/s/2("uSǾJ`2ݨp0?Os5v̔OIXVhJ۷o>}}Ӄg-GI--=`V9g3f;LI DNYHnz1-pkT}bٴilٖgǏwn}UUUڿ2'mf=՞9rZT殦ፕ1l7(h llaX.ُj\m`3|+MSZ@r4*r7BӚ]&k18ӲLζn8VDѭ{kJ/M }\则CZ,T)c`CǕ*KmlCsᝢ2{l'd\"M[t{B~MZe~<E;'A/?@x'3#{A C?@6L̤B.:3+n r5AϢc0L̜5Z~pQ7g  QԂ:{:ɞ/I|xt^-N`gʼOݿ$?\7)~N\H=a*e H4X|K9.v"_`/OC tZ[qp3$=b'$E4@ tʸWDbirWM9 N~'2,4@fz5Z 6yA :x6y\]um@3Mu؅C/9F1'w=$p)y}_Og~%9X}Au~ ˚X/]% 9(`4u=0p٥%e7d 0jٳ,# < ^נeyN)آΝ;tڰclꔩ6~X?W_{<[,wC(}Gq$Բ~98w[#?y4ge$31ΛQRU=@VI #+Q+VJczxg-3C›XmԽΗZn"Jªjl\V,!fڜI9뷗5s@YY6sb8V4nMt]C `iB'zreqp"yq' 'KԭB Rx5z{Ԓ|㪇M05R . T&aG;ι>lq_L_]IT<- ; w246uT@^Q'N5fpztkH;` sOk1u1i{Cb[$\ ]{FG_qN\:+ޮ8'~[P"A۟DZ=>3ذH#0v{'võ <Ѧk%.MƆu'ʲhnxe]KΎܜIư9(^RINnT12G[NXp5-+8D/S8)غuS'],;p/cUb6G`& Ak BDR(/4EcM۱u߶ ]u8P7C3@8-kH4ZK,=aњ+޹Jwj1"ꥬϕZ["幅6A/Fuj$j{DOF.rA%^S-|P ?U ՚ |`lu,6:5W)(`O*Dy˒Y zRe]h/;zBM{E ml،G+?o%jD&b7WH?i&}t(JԜI:Zpő8q특>qdyj#N,ѹlwdZVWK[9>d=.Q>bEX ?cUqea^Pڊ2K5֓w]ԛ&c@e۳q YJ)+ksɠgrR%⒲E&G` Z!JA.ɥυpV^{H^ ANGq4SPTi!+l:xbjKKO3Ο?xQQE~jt{鳴}f\2b1]W +WփZH*/gYfa;rifX(Rg[~!胖ؙ+ML12+w# U<9t7վ\5D(F/V(.zVAYi#J7!os7T7wxuPM Q Z_d |j]dV16ﮭyNV&LqfJqI)swW@e |Ɲ@DȆ{^8Q .yJ9$J K Ǝ`2~Lmg xr  UܹӞx *b8ng .]O}Ltx[}xbSN[ec,o+<ͱV͵(VjGY* GbUsrn}]ӧ "%oRDžeʓbLyAԌ9I)o%1W QcqQ~Z)ocJ)mQڡtH @*iK~Fq8o]tkP%Fy)J >t?R҄SkCgd!_zZ]o8wߚ'ok[7&c?|WJ^ v&;6bud%x;khƽQEk]r`BX9Ɍ |oC7cBߣXF+ `*6XqM7m& ׶E5)|>R7HغMJ_>QOHTz@mLa]G;n7 9.gGX|~/:dy>$6xG^C3*6`ɥ ŊKۑWqw2ڥ`dqSPAQ kDt٥ S"90MQ]OMw wP1|{T'4vw,i\6uK1sPfۏlDxOvƥW=.>EҼ9y-[kWjh/P(lo{#v!V4q&lx2ՕϹI3fp-yBH^yP(`L:T[dDx\%ޘ<%e}F(7QzDI&bb1;ms^oTb sWI>`ZKi5Nt&! { ˱\E=C̙3gΜwe/! h K6 .&VD5PD@1JΖ,5cɑ*!Mƈ6Cb?P+l TUG|Q‘!exl%ZšM"" (f>sH!ɟ2gffʨQBJj7@lwp3PțNuu5 ih])v ӆg#Oc}T `Q]~Ş]7{ŹUd&O*RwlԸbDKWY186rA*JD͚ ˅[':9pRO5X7m-BS&S&d1^?Ǎ-:cb}ˑgŹI,Jpv\i܅ lPAv*8L*(Hʐ:_:M@Ŧ'waр32 kОF> A {QD"on<2-ߠ C751%攈 b,k ] 5H *$:Y&DtGPlS+[eӤo> ו!v:+.ʷ>8& N! Ȕ;V&O+Q)gh8Yjwۅ2;}eFIaQC|-hdYs-ėL$q%`;*z𕇨h{d2swq2~x,x2]QnmDcٸq=zT)c\nPU2OqEk4Ve}@q@ #._]z|IL+8ouCD{3ɋi1XdM6_TX:2rsMqb0;1pO/*W[+6z$v}!kLj -˪/2$XA#i0?\a Zs:veQ7鬛+-;ZFk'ޒjHktP|\}2p 낌h/mJe- j#z" !; 1gp E2\*\k86f t`G$N=Xz3Kx5YAG†\9~i?v~cy鮲E};$,͸ Apw}um0lW/3ʪ&opsW2_qa(uGJc;LpO<YA_߬|ETui dkmIjn1[M ߭wHX* hl_ow*಺1P8 pL9R`}fپ wi0`n5diRe|$S2H7Ɓh?8b8Ր}yCU2Yɗ5cBAvYJ_h߳~l;gJ[F&Y^6^̱=)d.ŴACmm*uZ~YΡ0t3B"!3seּSɌy&']4w7pim6Ǐ_TS4|A,:5'ȱViiSX0iR)`}G*$mzz\Rz))**8<; ]YYY2fYp<䓲k.y뭷d۶my,K륪q'޹dD2Lnu<601"|1gB*S_]0mOO]_=&{C /6'QO*I02 a؝l eD[]mF70+ w\<'h?I<g2V6](:FWl <(H׳(~HiȔVX!7|S֯_/*9]mRrfN\&ISls,߾A+"Gmc=-CA25 &,\\~w|qļ0'P* Y@l*\|RX;%|Ovkў @PTt=Weh7`!~ao5.GE,R=HuvYHKm fS%A)zӬ4-J80]:+q=p_:R#qy:jVw~k39V}ԣ '7C BLp13j A}m1'Q$&L`_?5(!daB[=3rcqQ"9Qo !5!9{4Ol%Y_FwFj 0CC'\}zҵ0x:7kFȗYПnQ^'ptlr Lap{$/{xOK=.JCW6/R݌>pn30Kle`}A/->zM6iz!ݬ̈EǑ64T;~Y>xxW2RAn)NRb9au50l]h6)`}馊ZWw+HTƵ`vy睮}{p3ddd(i١^bbŋem F~D:WIQQ̆tVE(_&HMn%}2bjZ ][*Ű.m`}c.t ˑj|e[ylŹiC`axK΁KS<B 4qQ6zl0+CE.3 >x^&`ot^; TxUSWg V݂TINꧥa'ϥϚE7sU~n,ԅVmGh՟3F59zEԲ-Rw3*'6}8YrҎ<"TK=:x'aړW72]x+9Xv%ucdmwnr(ӨUǃ缟nj`:Xzc?e=K& ] /{m k$D e*m0F^Ѳj3ר=f t* a0¤ EZ3eJ|X1XրGNi9-;:/ɛ/(_|V~T 3ݹd'dXYŚz_`fQ!&h=kJC~a183HO"qP0RRRGx&Ol {)dz2qD9sT,b6P\ FY"yPl$%#I\x + X$Y=)VW  ޿ՠ4@ˈ}q/F>I$a`JDJ@&Yt#NJ1ӭ Hb3z X R< ;'a|=1#C Fftm$Sӟt`#;~m}S|8!xEh\01 4F=7(z = sW: ޡ44𩯳!kDfY/ϟ=6ίgiM9KpNZ eFk$WA3)P5|So;͊B@jܒbaؓsHr6T+Tj4َQlH8ZT) ꉿJMYM׌g/Rz<$+o$< sc{m9w%ehȇ,r7I҄ђe'>;/KOY"XcWV#e"hĈ~3H~~`B!y?۷OJ鴵B#y- i"䧞_ &SSXic`; *ò%`JώVp2j } 3ONb V'/J=lƛX#TйgNQ]ik($i yo&(S,@U*I0IC̿>cSGV’fmQOW]R ^]R AFc=": 7JD["C.L3"?~I􇃚yu/N-\Q{3+U/#ތ:+6!- e51Ǡx3W=ب&XX%E-'~% pmbȌ:S}tӡ ݠZ&Dq̅h.7~KY c$WӌhQ[2~hP?I芥wIqP>=bfpw;5|N ڦ~,x6.oI2ރd6wЕ, kLXAF6M`d9^Nx+n;X#e`4^>0ߨؼCfa[&TCF7c/50Y<^=D8߯ {"FFŸh@c&IK ɝ hƻ"U2$}R1Ymub^3¾CR~LN,Lr]N9$/R]UJmOߙ&9fG$; 'LLp.W9 mU-PHXxj`2N-'ґP(`R£^1HX11*XDv\xmѹ\TaTg t wR.ˆX끉W4+tF6.nA& )I7-& }t"X`%a,v[&焩H%HS#F: iHEziY>eH]8Cȝ_ml6@Cs{ ?f|Y_^C+䐓upf=Wm\\dKqF, ‫SKgjx L0{ rvY{,S&/Jw5 DC?H:ĺ7"SGxW၈/'Bvm8MV_~.[~om|ui2҈N- ?sɃ+e4b5演_~{Vpy:,qGYreD3R/s̢ӱ!uC"X-K`(~# gxac12S47$?BDzD\ߕ$0R]GI;([&/_.tcd5kրu98#JmhIfV <5PcDn$BSݐ7 tpMF_^[;fFܻn_pnٶ " (z:tP~S XOQpy5->weؽpk9CH\Xj`"ңH*4i|T0ԉ)lF>^2uTh+ VlN`@e`wn N‹o )o"Z_am">Q3ŌʄLBQQf0IRP`ڝFAqH+7z +/L qHH نmW;k2ZH;"@:XX|;yIu3P~ȞeN]CUy:1olBz H?C3$5$>䬃xbfLQhƗH>v{I7q7f Dހ}7vrXSanLΏȱtM*k1I":Amf*#5 SA,Q<(4nQ劄M/L򝯄. ?HwZm/ŎbD xbٳ0Aߟ6I4˦c m%=yYFe{Kd@IDATF` $ Ut̠f D4F1!U7(|ޢޱ=;2agAByiA `kʝ'`%^/bO4;Sd/( ܥ+Y0@`ˠБqތ6߀L~6F0L% F7\9 =\S6`W?x'Fm7Ծ}9F %)sri;kۤT]3$}DzH(D疆*Y?=^4#I]q1~<h ># 'Ed6~`hd,gŖM&w'>b0XF74ȹw)iks{8]m3>yQQ~$]K{#*]_!R3p5. @"C>#F,*) jW G$22C:iHo!i@.k6#bBżXτ2D?A";$MBynxl/l<mݸx(2x|"-oArw#b7O AX5P]@$B<;ƠTc?]AROӂ *p'ekEɆ)@d`^dѵ"l&1I#%!}"KsmnK%::k$$'Q=ԊJK޴ D7ZB-Dy$,30C¼ةj` U`eEdUG Gzο H7#@HLcKk AHd?qB|nÅ݂"x|NjQ nFOõUr]Ď'V~W萙E 22xnY e~i͝IT".)cG_"hG3N>miEcPz3Þ ][Ez񓈪G@8Ef~ъPz"tq }|AlHVdP:\Ţ9I(@2X#4֠\ed8@"WEU+O @7( G5 {3CE3 L_0&1}ۦhiK^C# Ç@Rut^,0JW;_wɫ۝F2v" 5u~zaH,%Bhݱ<Hl3N' xdI|*\𬗤ʞ.xU@̘3Oі=C$YO/ɇkA.I7YIr߉ _kj,IB8]7HHlR\\,SB(2RSS… RVV jglęs06$f}P) ]rG'˧+sh>|">`+c$[-i@kLF"-C⮇8G уUd!q6҈THLL:?ov'Wob~57ix,Oǃcj0NhnTft2uF']eg9~_s4Ep#cƉ/q&قwo d?WyOW(c_JeəRL\1f$O1 rێ 2"2 O3vHfQZڢ$o6Au,54kFg[˦p t[&B>@xf%}{Qf)=XpGK2揱Yra7 ;ތS,҉._{ۣwskI5 !_h! ~f1Ө4M>gd` D!H?71N_¥'y Y+}~P޽놧ܠ3H>F`O(D߇˨' u/߳&5BR TZ/Z[ZTTM+SuB(~}]3Ur=mp(w=ME)]Czq,t3 eY *$0a|_WvC@eggCԬOժhhSH$X(k洹yx~zKZ+J1Kۀ"f1IHCn=(>x<UbC@$qz&~L?\CjH $KQa|3͊9s )>n6Oqfj>,(db};v_&9q].! U3@} 4K\hI['~8Nd'Cpj~O@!nTp[8w2膴SnU 4g8QwSNY&d= X2}"?E,&`;}악SpsO hY&n}|e+c[c#ʝ#RQȀZ0ԇp3T^L;eUi~dUD?(੷3 ɎQ[j4<)yzȨ#{oz^> S 0d]o4SGxPrrؚk4"%=`'ɺJy˶ kU@+tO2]P/ t4;/7U"eO@ĂPix˓gyFx ,wCo䀒d1% ;E-o,%&[GWlg+x"P (JN=4 RGGdRN3؍RPۑbȸBoc"S`7B*`5% A[T^`.~^'LSM-5E)#~bقa$An=zDE]Nw&NС:O2FuQ4 |&Kc!OUnj0H&ht%lݖe0F$FyȾfĉ40< ZVinryJcK`S5Vf|L@ͽn 3gdτˍo4MUg,'/"9uM7c];Q9\ 𶏯E&nd6^g?rЙR+|o5)7Qk9½k$(쀻JEbⳠ( `cnkkc5ZGQjk/>/Q.$E951v*s<RVa* nD]_` Q\$dK{98q"# KOOWxe%|Wz >e~,,#]. &e=wZzP:Fz{͹#GMGm{\.9 wﻱH>QYDsQc`^՘3% HXFV@oz9{Q$CKSrGH.@C J1QLJ^.^Fj2PK/t{URBy`{s2OJ&4Bu, .m2uj4k!BMFoTlԿ2)-]#OEvŰgCh4+^0u dK@[Qϴ~#9)米dPCyd0<]>2+OdP@lqzV&+-z֛&3@z ȌL2E}YY|9zyp!j@UUUɑ#G& 6@=,b 1^LNW"^fk @!BwBQG" )b7F <|)ehR,:SM+ H)}QWp]H|Y]r-AgexMrOd?Q βYU+ƛo]V' GP'ua8yMEӲiypYQCl2DD#AeD@Xg\pYSS) kjV)slZbRZ<;k0mu~)dѽ\&gayuCp{~>ΒBR_?#L. ,zƊgl[g Fo}ӓv0w5+1j 9$4FߣMQ>ϒsD ؖ%{[n!z2;|lgBaD˟\<1p3H`:@|{4iZq'6kZO)d=K3M=vۛP-Hd mzW QO q2EQ{LV^\ 1Irt* Ofc,DG);DMBSj8bM&!}`?aBYݚ~t؎H7COZMv~ ˓lj,~XQө5x2JjIoR8&Dw fgּNJ5 A$:'G @>QK1SPe"q2ME "b30m˛>l: >A3 R%9|ZJiay|:g'q]A% -w6$!p0wD;޳7wҙ.Q?߿(qp$5֍>}ò}u8eFO[ &=?)&IZjJSuf.Q.Y!1Ъ #zWl!#=U2z $/?!tܦ:DȖ DE,c19Z-<*>48>|R`"Su8vO81D%ԣkųEӑЃfW֛Ӌ/#s$6(Xf*.{,C78ѿgEBjĽ :ZUq—½&(&Å'+0?2{ S8I-$Xb>uCA4b.yw `]N"R^ٟ⺠ym6"FYc2H@F& #]6w)WRpo lGyo#|r\z3<}嗌L ͻмbP1я.G˺yz2bjm['t.S&L*mܿL657^k^;s,_7^n+  En;"Fڃo+eLB)V"ݍcX{~XRRRD[[Vzi?);S*OncӉX0jNٓۥq+Vu`C_RMƘ3+,WmhsP|X C" )ƣ|6/oDFO >smD&S\R>;Vڂ(utqCb1M iΔ*1=nFq`j |ztQ:3o9]P,v}Ѝ Dgbm@7ӽ,:H_dQW9=2Q bz7о+X)gfɈ"ykАDqP`y3M o$xOxތϿjA3v^uc}L8/NB|7oeHpdQE;ڄa9RXN F!-oFyIfYTd]# $ҵW3N\ ov㞹"xvU/jѶn(_@Y kl{o+ֆV %nmٓşP_V}JXz^ZO}ucƃUA564OqHH awD9r<裲xb ,7^,c~(Y#; ~.I)J$yيaNPxsgpWS0qDJ3fAH t % *q@BZ>4*/+P<.ḐQ/>#S gCuH6v&.W-ltNۤ a*N2lc!hʉC6fMO,qI_'cN~)NY ' D'о&eɒuyvrI؉О^X$,0 M+0ȿ~"EnHZ"( |J&j %rpQg"Hjٰ7 DؘYuHqbO6NaQrӽ (pCtp95;*QGWȜsy?2]U7tx_O6`|=3Vm_9TW|}?nK=(qd:]sE%j B#oFˢ)Fꬕm74D%,no ޡS͘%G6c{*|l)$eɬ$Dd٠wM.WcctS R}HVRRXOxzwiiqxP<ΒqP }C ̓Oݓ+_C(wa1/ak,Ra oQtD$WFjP&rbOF |=*>B#^|#ֿa:,xb\۴퀛t)%#Ol?oLTۛ%&.]2 WExF6X*}'kޫsK) 7`,d[C @ 0}qb;tQ^_ۛeEotY~ТRY أ}'0@6^%P?}Oi<9K@{ hH3 sw:g'lm?PuNGy>Z=;kVfh+miE7ǰEF\GeeÇ{<yëcA?{&U\>uo|Fl]JFn4 Ì4"6 Ѹd%X0髃#TVV+Ln6pEvMֆwyDmjQ=!\V$8G,$O!%07˝VF9|w~»6Tο#4 +Q>V,Sk?w 5k2,fIW-N3n #Q."=Kd;F"gBCB]ݍ NLs #Ws#-#v@_ʛ>^"yFb7$&d?q^:;|]Mm-( D/9 Xa?p X\r&?(h, p&RiT.ѥ9vi/AP n7B|= :qbFw3t.@vÜ9u"x3Od@ Bdng\^xһHu?Oҧ*l; Ͷ>(KM+@Ј&X4H ԝ&sf r -+U~=`@ݪ<ld ތ@:QLje[ᢤYh[vviAi58=o =8@Y0Y|Q7ʗJu!O@Ϻ&Vl3!]ohmT5y`]Jf'YH;Bd9}w-Kx«KKh?[.';`̑'jYʟdÚ7$ZOߒ,'6,V.s f HYɘ&<pQ#Gѣ<d/|G$η*°:u9#LKHn\й(F>zŘ]cjmwACJCAT4s; [~?$.GTBDO>1Rr0M #@׾v㇑:,YH^4ZW gv"'cT8y23d?2'Fi'ýS[ĦQ b?}$O n1Bʇ86'Vx_l'{+-G܌w?qV-t" `u@dp5g-3נDq`Px$6jQ>¨XSDyq=KjxX?'l48^Ӿ'Gjdie+YPu-ۿuJֆ/w0;ۢw<'G-|>uG;-J^܀u s&dT`769 77JKP7D 6;d7]PA/}P<V`@f_ϥzw.f'yAtiC5-PR~*/)L]o`=}_E#qY}WdBP{^ӭx .%Ұ\4 zycʪUT;~.F Ӳ~,H󆙍qd1Sw~w ta\p8Y N>4_>cLz8c5p,Lʀfmb48́P'‘ʐq]F%0ZǑF|mt)qcaG"k&4Q2)(h?fwMA8܆˂iq~6qh8CN$[cdOy\@{2eL+Jh}*F+sԖm2 :R`ݗ eðEz'.N 2XK޼M X$t  n'tCV m(uN ǽ&7-L}%tҌǛ W:ȴ ћ˦p |~5~ć x"IV!5#hY l 5D끺]HpyXM1>+;O8Or0.{s d`k~µmIqJE~ݻJuU5%I&k~,eT@:@;%hi+_bD:;Ċ;RȊsʕ+%77|޽{dϙП!rXΰp_ePqΐQRmqX1;111 Ll2fRٽ|"[8b!Od> TIPϵH*f3Ls#6x@ZLhwq•1pOB Du)Ϸ 4ʽ e'Zx\=W3Yq:elhp/2^͆ te`\8mDE/Mm Ț^QihQO s7c zh+f;Ѩtc+}x~heR `6@%tbGnd[={BY op-{{iP<[^7F_ 2|vr5/NqhKSoIsm+\v^~M 'cPOsbWzl|-W#Kg+p7NZ&ٶ ݧZDv{I!M111s EPTl] ׆Z ];$.j…N'oL/mJuc5Eง1;7W B rԞ±:9]anѺ Hd6"u!b7v m""ScW+1|$S:w5ɳiɌ86>^jvyuc2Z@8N@jhD= vc␋~-9EC)t#}9Ԧ@Zڒy‰K@Ed1]M@c+D `A_+?_3?MCSxZ,&F "&c7s~&BjDgZY3篺( ` .I/Yi_{"c?^kW?e;j7K;oF=`!揍ύR׼Xr Uӟ|T(z rb0"Dtj[Ai;7@-?gL0-:! kep~ci/AXe5*6Blj%`9TjkemrI\b(]}]􁔝[HjI$HDf\F੮ɉ}AE=3Hwü^pyq,ñ-2qDp#G feU(鹶cdH^j/68&xzFGi;^#[`օu::3{lø g\rN"e+$ގwE}Ht#Ō51MO*"~Uu:HR>5S^fOSBR@o5%k$ʜ{eɈg 7\=*"s46q"V/Vdd25(p8O\P p#9i,+EC|R2alw eQ;x!Kn@Nj0; fA@,-Y 5XbD"yG^16(?gvrJ`*/OS.}r :`=Fp !~HuQ'c k`_ 3[Mr-FƯ*{@r iBUhwٟah{b`K1K7(m_z\8wF,wayl|;Ov(7ױyhz^ư6OUyC&p#q'\<AzJuUj4^bԨQ4\ƵҶF-ڊ7,z:8uˉmlYȑڣb^6&KC.X̌5L΀Et\$Mӳo;]ȍrTaxފ7r`79C|Lk0CZ!e$Hf(8K<ڔ-0j DT?u~ZdVoZ嫏\sbxXW h?qيb1OS $ta/${Jg 5#~ xē&\A'bw3oBa&*{H-p,[I(R?'^_" ׀'~Bs(EsK\VY=S!M/֥?F; 3jZ^w 9B~s!u"'MP.vG)ev> EݬPO,;Gl^y_=[9 3HfAչoAm0@3q@~ XĊ7S?BΪ (//e`"O(=uHm59s|6Ɏ7)`ߥAiqIp5^;٪_|cshހڄSu>õb!)6>H4 +NJJRSJJxv g(T7.wٹR/TS |"~::o ꇌvT@LT&3{ lU| $y{pfcOsf7oiwcvd̻s÷^AP_DNoEH Djন̛҃~V[A٠4FgOaWߙ ׻vcMe5/Qۼt4;vFH&h];-F&,ׇs2G xb0< `:yTb<ФMBw-"t4 P#Fu@/O&7},#9G5{ R`" __7,#gO0|臑s {wCY~AȾҌ,G_8y&44SQ7'݀_%]9-El3\7Dz蓅(_P[ w)LVJEm7 3_^ Z<% (fu F s1AJ^cZi(U$){|5Yr)DsxBGszZo;()+ ;_XJSi]^mhL@M`!xB)ڃgb:2SNvB nwYYYruڝ'Yÿ_|Lʔ8+N~ssL 0z$t:K`#gsKke(+r inH B)ɿ$vH6|@lpޜk%|sMC~b$%6*)}fhG)_>@4"P/}^r&?$ Sp|ϗM8nK <B3`ZP8zց͝51&Ii<>ދ8~~~63(v@Hsx4M('''o8`!Cj(eEw5P ۏD[(Nhq/,% F*Z簄ZPy1{V͛dP3](g;#\?O_}߾ml?z3xc'[F޺_t: vgPNiNX_r%ܾ1 I_y=?+J~EEg#9=, wdҕBiTG| f}?[$hEx}^,3ux0&fDhJc}`['o(q>~ gوuK{U^zf03vLOy1XjU@DnЫ[YWS&#N)SH|BxYټy> ݮH .Yf)kpx1bDN=|,DDǻ?-X4BbtQMσoH2FȺ \ܮ!^Ǻk=+Gbt=H>lo\1 Ϡ'Ь]Lϑ?o>ü* ȗmFR] y-:ߚ$4A&Zefypyؼ ; 1XeHGnă-RQ* )_2_n8wO/3B{lU 6D7k uF+wd$QzdCy+O`?G1xG}nS % |P0ۥ4X 4f}Ktdy3ieeE&>U5.W{/G 5O#nE{94 P)342 x [n&x?U-*q:'D!YO8 e`V˻hZ9c=@=Rn4  eŤ\|^/(,2O%YVt޳'j1/d7J;&RSU!r|l~ `=͟ap}PPqz9_֥cedd9vUji|ȵf5]^PD_f!bt+**I&cPI}]/<% ^+VO?-gVɽdFWjjwptr3P<_nYВ#Rqm +al8L .4C(Gk /XPBL>H\4HD䞕}ֶl`̈h_F7G Dg/iRt]^(s cMDh V.M_>wȫd!43 ."I,x9Ieg8`ruɛZ2oGS#Q=kT#X7+wg5)wW" XLtzC.ܓcNoG6uw >rz|IءhyoA;gE*3x<־`Zȼ, ( љ}g[vc% |GEŒ+ #DHC]T\.\ٷ#9qQw\&#wn5e5[!,T3)rDStMxؖ"ށi{ |q͘1C1hf䭷ޒrqv+d{+"/^|;rm5!c޷j⻁vhFzsˮcx_Az)O6w˜83(ge#g] bBzj^eƍ 10% d@m5Ѳ]Vۤ>I$> xonv~#/=nr#b7T xAsi`tҾloO[:8ؼQ_$ z8иwql$[MlS(^.czx`x<ȗ՝ GDm]%֋$v@sg~qK&WHp&*Szݢ6"ֶ.&R 3ѣ8 _ތE܏ E)4FlQ2_0&&w.:FϒbrqIA`Ckcn\#t7(sQ׽uԢ|\ov26R:Qq7dXv5!$BXfV~ p$g.Uϙ/N?S ALj;U68Nώ1$  Sgy9HI2˧Ε&qwJ$ >) cF|6vs]LEIosNo3YEDK3ōY-_ޞm?_݅,`8ѭRF Å 'OA2]|+먿-cW;xqXUHId[$rlE;_8Kދ~'c˱-M͖eQ")M`ID%zb.v{Ν;w̙xޟY>#ΖAo~2N]#'S ohqۻ|ޟyQmξ,` 0ouzr(7; |ޮd#D 3{`^Gp.8e~!iDi ˖.F! Ӈx,x mu/"}(C " ^9F},]*׊ %!9U`OKI4ɒYp9YO tBWE[T=$7 .J@󥳓5)2gR4trmYtsk FɭfL>]&O¢^i<:tx\@4Ԟ={Q^h;BOXlRr\.bՈqv2>p뺧UPq rOykMa bnk]%ϨI0 rIoXz.i7ֶوVC8H G춨0lUo-Ʈj0mQC D>TV6݋m?A"%r)2=' #Ž8$g)QtyzYڀ=/]V-H1jjG_KB$ N;I$ ` |" F &itwwKwz-!Sk#7ه1XtGg iY(fNF 'C]jKU4[sf7Y޾X"}b$1)մOaR= 6{H5j8M νY;fy}Oھt#EIJ+evٛ/ݍ q7N~rߣcL AoDAnj]#ݿ`/F)@fE wۂۧOO2jyjc`tuW}`xWdqtTUISc6zD,'cfܓhF7-x<ݢv97ܝlg!{R\fԨkg{ M>"nw꩛G&(!Jr^sV,M|Y!գZ+a #RQ-weduh}Vtl,iH_Fڇ GlfEncjR^S2sJص7cV=vY[ "b&u>|rځ,tC78鍝 'ۧQ[K'cr Q]hv6 BaaA_-NءCq[nF$6$dchg_\a7Ox[:iMę }ma% |xm㹜G$5_ׂ迧#9S֗MoO4!c2)͏dBi֏2m=gm +_ηkGoહK!uI/-v0Jœ Y97bd:xt$cY3Ǩeu/ԃbA)cZZ*v>lj)-.I7a#Yqa˄G!m Vkh˅iѲd糟ΰiVyiSm@Q"'ֆcO H܌B=b?s0.v;wwyGβE4k,!*F}ɓ'񬃲'ޤƍ&Y.CiEEWŤ$!xGvM7`\ƶMi(Oi )O$(Fg'ˆOOsi*:.N#Ql %=aqa+OGZA)6 dP)7;+4{RlVoG>oO\lf26وYJ_K~(Հ ]J%}ʲ ~vQ8E~Se)'j7ɴt r )Spxi-q`Pv-3s2j1:6~Yq-6.wyxoSdD>R'=|&[eVA-^x -c0p|Κwݧ;S32g* S_׭tC؛ A9Sc>$_߱~Fm]v]}'_̟hTشc_ZkVW?^Jg}s6,}t~va)t0sC]IpWetg:$FBD1NdCQiEd"?#Ш60%/G?u?+6aA7.]#D ]DUk8v L(%Tzzq0^Q&q@Щ߻&tfY85'e0e13_خv֝[Mw{233StW$ؔ"ʦMߖ.u2vk`^Ƥ5 `2 L|n} VQ[)]j  M _ ?% PBD =/mM!q}d(ӭl!_Gu!5UjI{F9^hhFNaD`̐ixN[P}St$sBN 75 ӝj)>#FuyokF3=]>sb{Huom阘a[m2WEk #n9U'LLL-\P~+LXZ/t =>Js`[}N8_d:~e [p(Nl4'ILBV\r7#/F2RLϱn/8%dcͲDcfa",3ǠCu ]uچnl H#E+ Fi3n8IN A:Ots-vDuQPAWe/x<M\'ߐ#˃w_< ^F=DUʩְ:!YX?BZG{˺ hd;N+0H>R"^;PWlpmrb_7 [ Vʵ?%\@6vL1ٿozGPf<ֶb#0\4ſS21GWDcU.gfS<[~W1߯?Y3 }gU:ք9!w_~3ZE BVL' Rw < ʗp.סu{/c.}tХnD@%N:jU%#nܗ@ W2%Հts¡Co.O%nN%9F~2O>f]q|GWhS('^O}? '[َAƂp+;#;9Fy!%,s0}OhPt&{Nyz.ItΌAYNw%H@hNd4Ztb^NJk]^HKقPl^5Zd# 2Ot#MDknnz_D QTjX@ԍlk֬im\hQRZZA F u~6v/+"U"@#Q#e ;Ę am ƌFjUIEZQgXbtt0>%,X$vlu,vSi~.u@-{~} {5rn!^zO0WA#NvrN;n*>Yޕ8^i9zՀA'S- '4{a)=..zXW[NW1WDZ 'QP{bripD[Qx?x"v 5`A}K&%gQ)F"2P'ԡGDrQU{|f*viMߘW1FAZ9dD} <#D 3F#sL?0 m Fݝy&Y~o !Hjld6]Eկ'hy>nx偅fy5 Qt۽t|@[A65C(zQW$7n+%7NЌnuUN-ܯFsDgx.wٙђ36 `JPU>tTL'>gh 0:#ZY)A1c :06vDm+N*i$>5sYD&1^bqQ';?9j*`Knꁧɓ';~iۓO> DS@'#wwJH瞓79g#vH[{%m2Tbt>.Q?)K֨dpq1mny@X}'QRq&G{&iCoT댵HǢIxjڂqN :\LZWZ w cOV~d>Ӟ*güUg3X)? =4쫗& OvƝr 69;$UފʛzX?/Ivk;"];笒d}^5;X?&%Ϋ>nIK8|S~{G6L8@Ué4A@Tݐ|ӅvY5H!kY }@#{lx jp%#)qȇ`d0H< L֊hOodf}]J^鄖r2OFg$0t$P~Q!?A%t=%0⃞.AWϵWq4 #7jogz8!x`{GBDAN3*և{㤜`Θtǣ [,p%}oo)<~ k tfN0ȑmIOn6tbbsKsЫFYfkUd9= hwEʶF6Ffhj'@l\cVY>Nrb)dΌRPޏXu{T :ahYЉL'Fjuܿ!;Fy#CI؋Hy~Xޔ`O)c؛R>t d6KmذA-[&vt=<3Jӊ (PHn" ɀzMQ1mbk3 cڐ>{_y DžZhWb )ZUU_j۩oYrLgdO9J0J7ڇMGCmn*V=/z0N>?ŊOsDzi'??,QCh\7U .NvKM@-rj,O#[&x9+ Kō2vW1[lM޿}"J iئ|c{LЕ̿p~+m0yQ)zX:~UvmOՃdi$Nd-@<2}ٯteo+ծ@N])<3$3a% % wgTYMHgYԹ7؝SȮɸHڥP}es!NQ-k6&+H?Cb ~uzu1w#;>#v@| EsHA2T[]?P֙s:.,1X޴+ o?$ 2XC`fră]FYڡ_>M@c'.2?zK7@gń^иI_01?FuUQx9i}1W{-.I חz6§uVydA;un@=o 6k:o!=xgda(r̈.lo[/ $!) S3sqS^KVZe<^9N1jDùQ M',?%KvHeN7|1$M;k&ݎ4$sCe2zCwZF!^o ¤7wڴitC.x4W6nU&C"oKr:QgOԔ/boSsgl"bCBR0%K1 cixO"Gw : D)û(ؕ4<<#/w D.|/㷑EZʉȶwa̛b5B &"%G^@uكi2zt6_7%(O=*d[dF@&$QB;'ʼn<) R<;\F7}" E}Y"^&fNp%pCt5VO*j [szw9īè~pE; ؠ0svU >;/"E"DQ=L)H f#l"D++6xtP?e}5LR_ dcs9͛ 'x;TTTӧ1nܥRrTb<%-}wYفwĨ$5K[C8)*+wC8ƺyU6#Ih @ӃQ"5KNesI23N:)H*wB|&D NccFKHahcJ4ӕHM܆0?^w---JAbr5f;Vɼ}BӻeeeҥKeDi72JKK͵~|?\CJتU˿P$L9(!(NY?9*YMX3npuN=,c0j~tg$RD/nH [>ۄ[sH\w ԃ=[0ވה(N#/" D_cH~ )75Ȳ% w@!pfLM3ur]nG'JnS9%^*F%&de/GމbD^lqm@7o`銦U& E~dvs#jL|1+2@mUZF)_ e n%Ǚ;Y}^(T5_8vIyG~]s D}F"\h)پ"IMUr(3%ۍ/c[bxXF2N>q>এ=2Ⱥ]Z;B :il" L"k.YcKys]j@hv])\3f74dHo,LQv]i*k;0g 5X9t"[twIl+ǎ]3AN&J"X6ܬɎMX"lA'e!tOH@EtP :`t$os8sIMIQ=2VGʘ%IfIOJMer𿃮5 <1_O .;v(2~7O]V+F`nŲfU&z-)))QD8srr~W?rYyW9k6Km  (4 ':Ĉ bh[{z Vm^|o Su-/T`M#iUUi:R?Dz ٪#ֿߪÁ9 )wǎ1p5|EemaaEz+Seê.& ?^Vi=IYP`?¯qlx~8Vh^1\|@!j20yw_I:}bNg3# P](cFc6֨2Xi }t `aĤџoufG6i`XO:qˡm=YFhD篁}b *#w'ffF6E0n8..kr $Q7TQfCvd806KI5'䁞ooy8sK5Xj&*9E|^jU.wסe5XFDcşvtkaO"Te䵸+bA>~h;s_}A+R~mwL.qyD㹓3&V3佭x)i2L<.r3 $Y85NrPWD,lADBgt"xiPeHt{v@CNG4 l2H4~tLΉǂYLiddB+9H.aA*5QF9~Ig Q{[o+^o`fϦ'ah'&9qtX[}rr:E~t phl7K~zMeK'ҁ NGAm,%~:Z`8%SfB뗈TԉH߯Y67} 2c&a ?=v|ψ6<:0=7H@X=kN|9AeOa4ܺr}@P edY|q<raF̦IHsFGh$$N 1zenDzL/3$LSsnD J1k+4i@^g}Vxv4inv+3~xyg䡇¹!X,r >''6yd_of͒{L\,|X&LXKH'+DZ=~րgQ43O#޴aLq!+ZW!Mi|z+LJD:T v cFk{* kw| z_.N]j.\GΓ/>WlNFal )0L^]OŮ7'H&IJ`tSeڪķ@`e/_.?di&N̙@|3NXhN }ԩ\?B)\Ygm۶r05_tܿ:f=yqDyGg{!f% c> (Å) )mq9h@@&uG֍{@l}xR#ה,._vӉ""S+ cH1VmS)KeA +䣃RU!`/:"N X짔$J WZb!ٕR_zXƮ~"s'SUPѪ$MGoI`C͟diȢ1XEAaPkүv"i,=H+S ayI1%{ed6edMO3l0> w{>#]%mj}zUF*Mwؕ8uB{&(r,gΜT 'O{\\ڨjh> DF#iW7"9222?:n8ٰabi6w*q~nQ?a `P:p6:ZpI@㑸wG ;2$*h]eH+z,q*"i#7!Hv!E* >D,5@_ 6VjšHF؝VC!wU|k>5=_' dL.+Ur t,/oR짍;dxD3@Kfm"^NJAR.[R.?tkjF}#3 ,29<QhgR67Ϸ>o5y]ߓicP meVLSwN-c)o_Qw+f:!0ýe2AFwY]YCtԄݹ6^Q .Q㽽BQS/֜ Yn|&2Y3~_:L2yb1H6>pk&쀘]iʇ06KJ\/=Gs#.g(?s@g3m[l[ ѽn0jfl+_Ew~My,;6\'[BJnmE{/;@' 4#i$gaLψqm;Wu MX>~Mh3`i ntЗnN5g7nC$^Cz8*xiHf!!{|b7:5l=-QLY.&>FHSS>0*aVF>)ڐO, 2IEQ.JZMO| O&) Ÿޝ,DX­s$f W͢9$ kwHHW _{q2ނnz@ô @@7)mS*@y5.rIT#=0*f% &d]x Ѽx BaIpni^qMi2+xY7ѡ¶w/)CP~%ZA`˴`/lyDɻ᫇0H՝Rz5yXlfL<'nF̢{t4NxƃYlck˭QENbUtƤxI,'FA,a}ˁt 4O Eu}$i#Gt7&|M PǝDi&DHMD=@w12%'QMF7`MI#нme?jc@Y, GnnnױC ML6ܑuE'3!NۜL{9y1^z%ַSS9M8Q-[&ϟb|nրR-qlG5k`@ܽڳVPuZzEh{;/ti;$To22PNgk9ca!˄(˒A2z@Sۿ" ا()gEZ0pu\)O{O@UO1aж=5KgũEJQ ݏ7dqHPQ7l#Ch@sk;m@YK I&3XS)w__9 .l0$+gQb1̨yScY׻# !F*Mp1?F=&:~ @}=wWEf]N-6·_Y"iAag}?B`HDB3v#b{qrzt_Hq}\\In+&!`Hd8]D"ł۩ arra=St"=~[>׶E5/YFPZntu'>$g*/}P/L5hԍ9;y6#LvQ!ߓ Bb="y:[ ōõ>hؤW 7ĈgEiX5Ci"Ж="J}a#0q' k{Agd#% ]8> M0Fqܑpk@oz+YN{ OTh#4A} DTԻ@jX'1>jQ} n7GG0jq~l;M+xRI0~} ~%e3qCL1f!Z]RrUSmK-51J½~N3LNtˠGAEi:;Մ=tQp Peɲ|N:lŁ t*7AZU/$ TDH瑸rKjaoPRl$.J-AZDpͣrJR 2crLˋܱJD>1{j;Bfgʄ1hp$LSSMȎk몒Ȕc@\Gr!V9TdXnϝ&R-F`J BEF`]H<&D]ۉ>c;"иi"껎5ק@ӄt`jH֗ȪI G],Gp̇P U!w_ 4cS^S[w4|޿?x*v-T)_/E) ])tX~h#'h#b>}=~#ZF|dؖ*A_tRcAN-biw$-!> DNMٓc$ ;vGytX,k'Ƃvf!K4ýU._`j"!yOh {_ikH: jMi3M"H30St̠$+}nDMt4Ld`Sx9}1%i`M@y),_hQӅ n; :|Ҷҟt̙0?@ںub9aѣrUw#Fȑ#.V4 'pCq"_!1A>LV/" cJ{uq/T;ȒLo!f} r;rU<أ!q7~Ʌ#Hl@]}ĆF tŗ`4uFJ[[H " OCH/ ~{NKRZϞ+'U^\W6)D)zVmWBsd 3bNjAw>}̱E;>y@3bR7sKKF!.zӂm'8 ~טA&ddj|p&bޛ+kv'j!ͅa yQ1L6è9{ P#Ui%_ `O<_7I%N\. 姤xbhސD! MiEθ{+mc? /)iGf$JX dݒ$Y3?&Į{`{U>&ԉ-&kw#iWЂq{1Hw!ݍ)6(RfFfN" dhIdz%,5Å\Ty͵r#IM{tls;u?~\2鋔d=zt\MIEEE jlNSEEGG-)uXmpZ,nȕҩ2m#T|V:n]w ܅ R x_evL CI<& ,&\ *`/<؏MB(1>F]h&8b}ꆶsV㈀ǽ[挣 8Ȇþ"и_GK%(6pF}bmªp!VoV仟nflճQp4T+;${vх4,+ D`En $ջyna`OzL> ː=눓dCLxP8n/Ix(p{Ƽ Pd6zc7Bmt_J1fU0'1}!m̗ "'Id)rsԀo02Ż/o0O+]%u}&uf[40Lx<ճ P& bZن+A'<A6U ZC /(b=o @'Lxq<^ tB*a:q<ޕ$~rdírE6k#g>qq S.үz GC&cKi($8gh/g$I2Q1Q`Rĝ[:hlAZ~e']vD]bx_`3UVVʁ܁52(r P;˨\Τ㿚6e2jRo\ ) =H/51v2h{·+mhkVJ~E-fӽi*@ڌDE$P]5&.p0˄<\~6 YH^AtA`-㺘NL"n]6&ihuslIoTlރZ1{ފm\N;4~NN܎̖7\s0Ek9l-JiB!+$:Q 0,_d$N FD35W~fѠ1ݬ)f%I*]Mq`xj`BX;\v@}* ;Z녮wHk={V9"ۚHw{݉'u՛8btc` ,ھ0)&䩧LGJǿ= hi5D5q9r2)Ylmu*mlY3Fڎ6$7M#+> 1*#"SO8;|3H1|kghGfBdomRlL0WWAt"t]+~RJԛ PkS.PNJp˄,D]2xd w}\RV;]IcЭ 묷ཿϏm=$-7S ehW.eh]V=x mp L[e`\}S?;S(˗ Rt] /Fva%"3: oK*4Z=D@*fjnزɲtvGm4灾zzy[d'4F@dD쫩z;}MA_huWUNB>Azi a:αXHZ7@b:.]شdn 48:3sK.g矮W&/5)I&61AF1qfrI#; | #2O^-]1?Qk+؞XU[r#xUcdܦ?]>؟-{ޔS{ʎ(D GaDz{Ƙd1\ir&B yQ-H!1Lʴk}+4]EW8L0#5B\}\o=[S+C[|K֧Qb% ҩ˩xf,"p?cӢe:")%'^{\OY'to 91Bl({85Y%nvE͎"'VT2iQePl'2q7ԙЗq:> E/ݤk< 〉z7S ӦB,. !ӕ:`6:HtYjTxzlY+{ n\2z돥#:[f?FC M(o'z.g߇IIL ͆s[_tϺt97BCl=F߄1H2 ^5 'DSa(_uZk' gһ=NS&%.fH0 #AWەA!iO] A! ~UHp~iqddY<;YEL'+ מ*d]4}G(86NWV^-}qES;?nG;M`,Ήח.mL55Ooh=zOh(9hكqVlx^ 'ʒOd.u?3P,Mu3P_2a7]R*1v]`DoBXU!7;Xggj2#H B{CFP h7Ay̦;"к)qtczkg0k=HB9bd]IPtUxoo\.HvX;r8[آBV]) %G$m \,LT@K?L`J 'k}O}pc 6i&% 10d J fЧeVepʶYPaMUkA!u]{܃ $ҟ<laj\-nzѳF4ǡyhegtg%0 ESp΍ G3+x砽'fr9w몯FA-d>={ @JOW@Y$ʦ#?|>ZiO 6F1̥rѭ x6_}؏7XWuN^PvBciэ D8[4YtLk 5h m~"Ot"Xtbt3G[% BÆ@ KŮ!O6 WK;Eӕ7+GzHlIA<T$N!MCJE=Ӽɲja,$Ij *AEƟpEЋ](ugCxoNPsCCݻW͐md>_/ cQb=Zi=m!LxbZmO%oSVO-K2yYj,^e[ej+֒BivNoH[5Ŋ@ b`ր֏0d<b%.<n"HRdD"}  >HHipD+x;ڵ\:MӉ݊(=wϠ-*\mM1{R&N+:+A&ý.S nw\#=~U>$.5CݡJߡH|ŌpX\@9W =t7R68RtRB̜,kˊ)2%/N@`:ُFP## q0tTԻv|Ӿ}ƫ%KA.*hE?Ƞ 麘.?5 LL2CJ&'ܔ +7eT6kLX-Z+9 7DozZ^b5srE(;*Ej!o4V!J[Lf~ z]t$2d5Fl5Kn".0Oswn:V$ߡ[i]Cz).Ko﨓xH1 `#1`n˾F7-F)|r:RY_pJRF/@g' Xe4^nS  e3 s:KtwҡeqЮX #ϕ.Ji mM6ʯ?  ђjlXlQKQ̡DOUMk7ӵgOW-;l*+}1*9_ƱjUCZ]'WvIӏ.S:-Š-R>߾kMlHڛ[[=m駑o~,l1p|nғڄSN+K8^sïM `Wqke`T?F :Sn]t">D)%)+޼{RW2ZvUc8\m*v,Q{ռYiRtBAvO˶Crib>];dd6d#i i:^5) ^NsA(= )z dr89'^Fg(`ǵkT?Dd=?~jϘ"'1r}AI˯!jѢE |i~#Dt=d2 ){C̴lHiEKX~FIJJ ƧH㺮6Eo$6WWId[$r8%ql+VdJTJJb`',.?-;/;;+{n T.[#I!Kw)`Hkʜ׊r<7#/ODƝ=V [AdV"(S1">M)6p\"[j@ ~[{8oi>} uk>=;s0uj^lQ!ur0A{C9xRN_@z.dC/I!Ѯ ̩B^4І-PsLe~_9`FFAh/nӖ)`MF&]qH krP1O/@{ȶ`շ`a&yZ׬7u!`@QGjB\2"usdi\׍+m{v" [2cƳĢ6֍l(0&'bNӮӯϮaU]\ewe.vaZe* d6^d?5[eюCd5A#dRߪ@'P"P7%\L'%$I9Ac$L'lMlh.Tk bSK`j@B, 4el' ;RYдT+Va1/V>]pwS`7ah8p<.SLT̜)KF5B%~Wƾw* 5ps]dd(OIr議WJZZ,ZH"#=co.Y59R&~OZiKWCi Kg%''ٳp}J~b2bbSkBRe=:+XQY!"snhąȠH?9A&O}DzXJ~gImI67<صJvv۫Xш˛k-rՆ(n62y3}"FoKP^kTWkþL]~s>נ3%*{*xAv)-XaCcH3׍APqș=2~xlO7'4ˡAƼsH҄'%2qF' Er22uadfn4"(`]!Tm ֎FisoNxe;"X՞Y鏩D2׵m-6f|;u ' [\ E©uQda]#ck1DSՑaAQۑBA*cGe=v%pzlYH?|-vH,W wޫ^*iҶ]aEJ{UENHΩ,u5:uf 3..1 WXČGV!d<}JڡO395 b!20ZEؒ#l6*e1ġ!p f}p.ozQ{d:Nscp%^5zd9 Ύq)!aQ gUG'H֡Vqjﯱ#dס@l˙3gҫOQj۶mױΈBaXڮf'_~BŸ;3Yr9R'sPLAx(zCfk3Rgo:뗕Hٷ#CcCdԘ8$Y-gI\AJ}Yj+۩^_٨"j[kHɩnu. |~xSӑF15 >0?=)lïtIO=ܥ}S`Q4"T4;+_T} "%5 "9p• yW8i6 ,|z~liɄWr.7ԬafǐJ?85ӊ+3즥 PIE:wͨk{rYM_ ep<;]2jZdT8a1!560IҺc8Hwֱ\@?"f=tm{f"ds U;ш{ Uj<:ģ`H4kK5GCo4=]l!e  ݜ#ׄ3Mž5fE_vb1Įm2JmE6XNHw24:q&lRtZ iXyt*V`l=>FngdC0sNqf%!R#唜=8WX)L2Fs@:T΃%r dьH BF9<v_""6!\6 yT(ѣ94n8U_:tHK)+s2"dh<:L=)1cdʔ)r Gjv<Z}э7<ԁ#5̧OYU|~F@Cr%?&RhpY2r"x׏_Pl75#"켅5&I$:RPffR3hգïq 'BPoj@ Z}7-Oxb΃իj>Ѫ0_?ʁN'%:3MN )ЖHTPvUءq]c?a0X=?B.X~;I]\܋}zЪ]|CNh4*?#@U&L=anqeAF =Py}y=WτH'Jy2]F!A1qud 7$8rܱ CZk$ʦ ^ *ijkԙ!Ӊrў6xMWOЋ 6r_fZD`eDڣe 20X2nn@HQ!lTl=xd1$3ea}T7h4TIMuu)>*zY׃Ľ:;TsaDS,+ ES2{|$1\ενa%zaC*rt f_߀sަq@B)88N5$,ZeY8=,Pˉ0m.~1S 'MjP?rdO mFP&= $^g<*3&DɹUJFj_|̘1C,Y:u333?npǧeʘ0 !/ZO,<<\)fΰ81B~ɤIzN'A. 6U$N Zz{!naltHn'>=AF?񟒳7Rr|45` ==?Ԁb@$,(Ûd1Bt3*B!u>ч5-c4B'p.7U F#)}BxC2pko`#w؋jzo \CўEKe҈ 5ט+l1Ȫg~=d?U@5L jTq?iK#tpVKbX1pȕ\hFQf('m ߕ+ |'P3WɊiK?T!hN^G1󟬭o%stUuREސbDȇY4f)'!ƳL'N'jL[NjN3Dž@([:5?"4(tȞ5ٞrtVt"퀿 ':qWW˄ @`|̀NϚJ_lBzcl}ypslIqP2'dG}\)Ytڭ2'9 KJ^@IDATN,'՘Q_ :.Bό.CKX՛uSn9kF:NO]/ֽrpN#Z(P9bM{'g*|2|p7clO D` Ǩ͐ٙ^0MD֪lr7S68;V~zF?UaEq͂W-5SzU0$g d{:ԗ`eTkosɴ5714ޫ}XFA1~>Q.`A!yQ?ټ6%M |bժA Jpl7 8[ njڍ%fP9:,PőMiC+rv Ūk'c ^9lrK0bXBbZi`S!Xp[tA4f:/~B![4ÄF\'8acV>sZMW0ƊI7f+BjϘn93.}{!끹fY` Ig0Cl}.5{!ލϢ4l7n. v~.Qc}_]u{3 ߏyi'tf=W wye#b=e51 mffJRv%ura/,fE KH榺gt(ߩi5M.\ u@bcD)1W- ciWjT%NdxWKI_ FoS!o4~J8C3آH5P&A2{rHp3@8Bg5~)#09tRT(;I64Ֆ 3,?8$c˓%º~=1 6|w$999vZ߿tg.\_]d8:\;^&sI}0 % A &h&td0<ĘES]}W6;r\ I\4$ԒcxRJn,+ŲgGx.;/~sv{O9NdoD1T_U?Ͽ]m;' sA^b`y xbY0dh[N1'׵1!?}̢g*+it2"§9GSMRgsx'>2<@fOX !H+Ew $b0X.ħtBd1 pbrJ,e;RрzfQd$F++N2kqmţ_\-΃No|l0!8AApap0(}63 ldlu`s56Fqf*03(J~E)...by>8mݺUxnCmߎڦ+..{H`ĹҤغ-cپ:dM?_.EXgXV̂8k UpF|$v:B0soCD<C">> }ӊ *_Yn=x*1j [rXAnO}spsRbϝxLku}u &b]X'RZ`d@_5c`8VGeΤڦ- \:$W a?# LJ'rEYlA0*q_mp<0'r3Đ CG$NL ޞkgh K=c:'TǛcqY'ՙQT :Ô76Jg[{ku2h&1N3_.}v߂2Pꅍhϻz2 9\'OӽE[{%$[szTe([-2cUBݸa` 0l[.O=V:LdHNИL'=ĉ$U~2.:Q-qfӉʆ_ g?~Å/le028gp8(D2sb L:N7T'n;Azyy}ldiwሺSɉrpsbA@,C8lx$zp @_ ,han巿 /9` y{weݺuRTTd Ȋ;!f< _x%#|dSAȚbOɓڢĖ+,p@ҷs8|%*hہd>5^U wdBXaQeva5`HG9w;g?I C/!`Fx ?% 1Sj!;Ӱsy_KfR [~qa* }q o׀Gj>yZ=S.'y+ϯo*k6&$ <`ɠ: =wF J4!>].&m3-!H5 Zk $OUUs{m:~2gFE'50/Ũ14 l]'λPߵl?8%гVcdmPLf'pJX?`fhO'O%CBBCz#3ad8 d/КYfZ}+MO1].:Nxtf՘pq;፲ ҼiA3[ LE(O,6+R3k<2eLrπzxPH ؍hd5w%/84"YA?oKEiNPdG:aϳd uqA7U tk`e&U"ԏu̺I gkd=_-E`Pұfy9pS uxC?_'LుzB-cɒMX]ssp-N^B}Œ1q=)3A!2kr̛!FdQG] Wk]_I6!W?^~ݻW~_+i…>g@QjÆ /JFF FYOOT٣t7sSGlؠfa&98qBO+ )4Nt܃ΕO#P|t'+݇~8C!g@u=q\a!۳ `!?#ԩKA! s()1,:C  _>ί+ ϶JkwZ|cYj8|lR'' ,cW /ߨ-o㮫'vbd~5Z8C⯑ƴip@MHaE*9^%\.DNhT@Maaabd޵SK<3Ҫe;2tj:u$ӄJ4 KWF쇂NgZgp&losUb7>4v9 raY+FY qcpyYLx 8^/Ƈ)S(B r{z۹h+ktț b0ܮ]0q(ҥKu7j41矗g*x3&F%!|Њ>kb|L@mR <h"=z#2q˖-*P;@X`[rƨUw4fڎ+F"96b ^p^/J\:ٟS+%̎@;9æ9X)]?\ ?g> M'+F?)CzAD?$21S4BL)8ޡX*;(Q<۴v5csl*C4FٝW/G!SRlRWproNO@`GujۡO}J(]J0y`彷DNngpЦe3סg؉ ɴ tt`n17:,"YiHGhx]5vICM)S#2UF5~=mA3%žóD#w -q4v uCV!Ҁ'm'`+fiRaW=P_oVS&5fH5ESmR}{xC>Lucmx Ŕ a23$I6|6AJi#OB㌊A]vGF]&=z v2)J"^G&ba2^,8aŜp3>Xb!ލz^wDөAvx\EH\uSLlzV;$@uoh C.t&!H^4餻[g w=`PO'$ì\^SL@XZ0qkܓ{gAޥ - S|rby}o GCP@|٣P/_uPUU|NJ0*\Λъ]@!`#N!Eaװa=j ߴKDo@]#6yuD>>QlvړkkJ) S\R WV,eN_bDq1M)&yt A%0kFH%[gx%!֌q {OB(Npzqf wg}ݙ*3FZ BHcX&3!14nH?WAwŜlF wW=ۆe;(iE30]ϗY쨍lOkmp=dy~oT[RdQk%LHF[Ϲs秽 trd*)YI]PS tFҀ =aP,0|P&#E`(N/Ue :tP7L'֌jPLZ,xZwZrFW.9C8C8Aaq47p8ZtdL Tz;2؅@DGw\S(<9uc ]usU!jB? oB__J{͚5 Di<V'G40th@w Be(I;W a\zUM4IM3iǎ7b=E5`0P6nVT2nH#轸ٍ֡:ّYopv F9W|b}qHp0' IAdP@x\JYe¸ "0#SB).c-(VE,`NR t $`XUbFcFՀg<6O3ceح5Z^_WH|Z!14)@ >$BN s]RZXU "jQ'ܰj~94].˖q+n7(cj%ݶߋTɦ֓ެ#PÚXYaXWVDvT: pvmգ(ѻb y;p΁l뀻q"#sC+3ZsVf-˅vQF2 ʘ24`AQ otz@&y8NWGrޔŒP]da51`UO !ˬ wUوRO֠3W[ sdUƐt"@,u!MN@Su#q5v|? C8qaO=725*x?Zq1!(!tb5M'2o,$̳aψ3o< P fK~Qb>?~\PyiwCJ\ڵk-̠!V#e͒8/ ߁;r(TvFO 2Dbcc;>lk)P@x0@I7$Q"B=VN+w`;"luG[J΅L8N[ Z98A&-EP*  Oi YR\,x*JQ g@!yػsYZm\|ru_uEm~.?[5WP߾[Fnn>T CY%x:&;Nʈw1RTsLR\jo<( $*+圴`YmmED(֨h}mwl^0ablysfGRJ0A0'̐E@&7sGMzF j䆻M6i}j,Wɩԝsc6BP Ym dߛB㴷?۸d0ApkKSvѥC&ߧyIg*'pPv<_;N/}Wޯa:mn;Vh+,JWvm\KI۩ ͩDp5@s#{dNL!H.cݚ@b߉yRdWdB,%n#pj|}uoUI%RJ:U!s&W>-ʅLh:a1a`"߇_WSf,Ysvn *">1@&SwEpo g&oYǪ3HљBR*qS TTrrG(;m߾]~_(SAA:6Of0r8Xͨop<'ѪxtMSYY) ROyy6&tDL"4$iL&N;|}:}[zy cKX4%4.\pOYpAvhQ~ ~ YgYv9"{Uܩ0UTx>:c?Vg 5q Wc>6X-tGcj%(#￷\Λ߿}̧s%e#kD>[Tȃ`9 =@A4f̮j*,j0\ή5:\,- $g]h 6 bv:^%@ݭ*?HdL1YBѐn6ȿ? lv]b JoL?>٨P\Q,7˛;>o) #XÉ:;'b ko>.4kI$c6s3EU6u` 3)~w9pE{Yi{,*lU)`R R="͘IN6F!qgXVfp1 ^+vARgcNU8'W;C81OLBVۮ ku|R^uPV5Ae}'Sҳ^RVV8G\@Ǔx3#EӺuĿ xM!r,[#`e)@a[^>/FNɻsFSޓsJBBBN&~p;}ih`,Bq۳ض%!(˓&ҝ{ùFyRʫ2,nK(Kp?a\#B:wN\P O#S  +"͞WM۸ \(oڈJ\u/6?w/x<@<X~gdJ}]6);%HhH0&n6Gp18eA ~1&ypQZ0rRt5UrN-'+AwA#{b-3X;fV{q& ͨXVm{+ijAˈ#5?1Ef%꺾v,Dol#{QpENʂE?`TMJ׫Ϲ}tjg+8+9gޕ3"8nu#:M@xG Pf-e1H=~1A>_)y ٽYpI& d A _jO Bt|R_:qSο? gh'޻q.[JNBt W^Zhɓ%"2Ap[xKPaz#S\P,$2 ,7|Sn0UIJJk!g*>PxK(r͝-{|̽#R薇5 jCiu/D]#U?f۱c^CڬPaE9cZgpvдmmrX1WI}I.4l}l\;!^׳6qu(x]ľFo*+pé6_l3 :g=?k@Gs]XT mBLmN5UnT&&ǚ!pkkuaBT)#I@P$:a=EWBj"\gs(3 .u>E=_AIay PD $d zFv;v8CxmmwE6#\[cXif>Ԍioi*}nW,帣嘼>񣘸7[ pGQnE k獲:[r_|lyH@yE!mѴֶ|U3K cdDEV]>U!"<)A2\ㆇ+b2b!i>Y\T_O:0+ {8'\V]P _Os"bd o}5QF A9@5(߼YA{RCd%4UWWKffʦMkNNbHYnB^ې6B>,_eÆ iFWW`J\\7AR̥*B*Q|XD<3sӟ$op6n)"ۖz`DQ7_Yw4^֝+e*\sr7phgvEjelqDN2Q4g?: eƁ}7@oqZ/V v$Q\*v1,Y]wx 95rTXr'N@GM|DM T ?ў0d zpIUۥ"?UR?5eko_]@}(ZbwEY)m3F9wptd;j.jYg!?uΙ3&5Xc}P}=1KN4ņ#H;Py7B?bio3cĸGf,4ԱSQ ~PBtn;5掟y=ow?*8[zq5G+/dhG'pgC~D$ˍz4:2SZyyj#U~VbY)mVvAW!r1D)Ԁʓv>SBZ8'#\-Jco(ؓpQ*ٔqhF$7κpuq_> |.F==P`sl[, WꔓՔOd=e>x!D@YGCBd]r?|ԐgfKv]nUvl] Q}ᇊP0SV+Zp@ą)$@,8I7Q"ip+uR]pE}3:7.ɾ,;aqN\c;7 tآ_?*N:}B)tdp+B68 NM 2 R`ʘiO8u 2ͭ3\U^/5];Z~XRg\oԚ!(sܡfo`L"|L*F`DfXЪ?1+3ם.< xldRH汹bW'읻!~ku̶SO\njev;2!ޔ'Dϑ/$t l `xݔ&.0dF<ߋ+;A'V+n;e쒺Bi>YCx"|2mlM0CP=]9XQ9 S^W1qi܆MBL*)Nm:bge~:} 9!#p.L|bBo4PEp x\>8 >zq$)cv>V|FyODXͲ`zLc'΃er\V!]Ljaܳ(NƦ:(uSc"h5q/5iRU%6Mɷ-qvR}gΜQ?X%!N zOX'I@}S QUc/hO*g\EC5߆c ~$vۣx?ٮ=*]r!*PpS2}#׬ SVndGsܦ]! RL2,8")@V >+R)sNc9XatNa;@qe$'dywE;H= ,h.baWlT}.>FjR哛F{ )Gpr/i_OȐ~ *k`[iFFfġF-veb=.Sqw9rX )kjkW䨯⌝^\+ 5`l(=nx,h*c[iUMs-<Ŀ@Ǯ" /Gءia(~r569 L 9 pMG|ǢO¿ Wl'p,o<(RuG5'pcF&F[1PӫJ9xB.\IsUArR~0+vѲxNb:QОw!~KQTVd vVOX#%%%DnPv]yկ~%OVZX LJ͗HG%xHX-M%wZ/^HR՟+Ax+jMxy5pժ 75j 5@ *‚Uf뷺'4nn.d^v㽸Sпj7HKZ\CM= Y>fI`,4x]ތ"WqAS_SC^#Y')IN:q'G 9T&sS#f MvIn!BbzPdZs}\5bPس|_;a knP)&N$*e}QNc$cR䙯UH]iv}lX~+5a1!b%b;tXd"Pk CD%&"fZii+/ʥKZ@8)< )fc'|Gg(bҀ00XNIy5ޛߖmGFjIGvkx,_?=qb~ j@ Tȱ֘'?E~5@mh᳕r Bf[d}i=rY OPL5<ڵ{lЏ067'j8}oE ⋛\l=f{F*)_NEۤB?&"@fS2&9-@I>twt] da\#XOЩI328)&V j>R/ ykЩef[pr]7BVU J[ -߷|$  毁l46I@DC{D2 u;uPsȣ#eYV}1@G,ñ4J<}&V+Vȸqxz[*=zTec|E( qԕƆ|0DΥWICmdD C`ty^kkIpL\i6c8FCl?<)VݑQ{DZmojzCh?⼩W?'sYP8rx,A,(JesC_AH"-chn@|ϳjgGA$ds4|v^NTBKΉVNgkƉdlEL Ewʈuj~M՞ 6Ԁ -&ǮcUCz:HhZ,*!&FLC% Ӎ%=-myb\ 6 hzŠ4n1mo?:@+N6ztuv@(TgŻ=0q߶>q*03eÇI\FVNє.֭d=zȠA$!!Ae T< dΝBqϫ}h[`@$@\<:d'3!*Mgwz0:bT*8 s֑}s _-[OltzZjPvր|׮m)<~>tTgˤMM.* Ym&bf:(|ef5h*oO$qcN]aBhg:T6."l0SS 5@Flj&I&d sw۾U:6kD ֕fyx]n}Ԡ4_O3GZ?yzS#l1F%"]_^S8N5(uQ6Lg(B错*'ޑ ZN`tM;7a<'ɒ2yA(Ad;v=~ZoGsUrw脳S`ApcpIO=9PfM  Xop{ {@hbZy9N#V.Rr"\9|gXx|>1o4%xZ(xb2.EDb/LRu?d=2 bP\ijN:C6{| $3kՠO)(E>L #r\*%%zqM )mI}_"Fp;"8^Ì @͚Yo]6dI=0o4$@ \/"-![,8!zb3N\iTϖL6:׸޴&44ۖ/O^i5aCp_RgOȴl=os AtJJv`:mɘA{@{  >!]yvZ^SeU=W#VUR̕m3E#Bhe~Ș)'Ȃ%S\^4iB T)&d@IDAT+g zpe# =>Z}{kvdE&IYN.n RQ} u&ihִ06(A)Ę)mm]jCf޸&ݣ/gw#MrLu] ,σBЈ+M,f,;(3+-}9yd m;Tڧ7~%Tj3T< Yo\fOneSM.ٴ6O߅2p,GDnyM5' 0Jw}}='k𪘹{ύDKhc(7K-:)YfwNt LW=n,:U<>vZ6"݉ U-"ڡB-2Y6;Lƶ)~Z{XNl.SfWS"&Ζ"Uzx9~ F>s/Tylu?R_>>f[[1g"a#$Ĝ$5ӤHWBH}cx NFX>- Mfrup 1f|&/}X ol=X!0YJt}Z OGWKQiTfIze=/bbeA+ypfL̰/=Z)t5ڄU֛Ai>&'2Qo0gv@0}(Yw@kI18lt8}U3ɤa&Y9Q Uk|pOH3&d]Q]3_O,hcKi c&] S$ZGM\Lۼwb7yG։t6NIQt}#u29qBµ-b  Ή ś>` ( 4wj2!FQ73k֮@C`0\$&h64흺֐@9SUv`"S؄!w /Mo.DK2v{E >1}b\.'ٗFJ~ 7Հs7{;F [60"| O]zq۶b*3T|ܢ:˗`?=}fP#0wA@B$&?A=Γ+pNk`0پ3e<}:zu19u 4ey(SѮ"V(pޓza3؟LmJ^|`?-flv9~Q>=еs~W=R;І 7{j= J\"ӽeQyػ*4ǥӿku<]bsN#[*VsJZW-$!4P)>#+eG_­2L4nN_T):Wp'tsFabt׬EiwȌg N/7x%c#: pC$R߷6د:T Mm[XqXk4:p@Xk9l~;~ՄդQGsQρk3)7`<,ޟK}U:9M^{w p9JSW5FzKKk> Ӄb }ejY5u7l\n=, ɛh3O INTWNC$dP[?H`Y%8#dOB\#DuF)ٽ*ɢ7 RQC{/jw5&ܠN˦Am2l=p;mu-j?&9*k{v7+-rRc-e6Ղ&u,%5-u5ӃgzW[C|wXe$_=Ki+Fl9^|V@ ӐS.>z/1'8d69p֠S  7}lNH.Ʌ^$j]Nl9+43wvq<-_.,@WIl6Yy_j44U5h Pu: TdXJX R!M)MCA6fKjnTaavO k5Vu15}vo[ nK/CzMVCL! mGKʦ=`.N'qkF+!$%r-:<\;,yD#-Q0&RO?:5q"7'`R\#2}'P ytf= ŗ"][ L?_ B *W4+F̎b!2mVg}QsHAW4M |<d<1n#ch݀X1c'ń B]txGj*!զVY5?\N+ס3z{PrtJRLT:S @ f+ݻNhwTy$)NDiKۉG`|rY C\Ϲgp0˽b! m_} #|҆6 b-aq}Nf::^ פ, {]osRX.!.91ٖ8j}v!&Wk(qiP9}qJP?hyd%USpQ`h]]SfYN=a6z}+xhc6DЋK_دWXSN6۬aϒMŅME~Gߛz͍^-NxګR7Xyp\6ז ܜ, )eVx!p ??h&1 !~k'юYAv=) ˛Mz,(_*3h宀<YD.umoOdHk~x WnG[[̺KH 0?hj*ڕuﯦ!f|Mzu네~dw\>h.%%#OiGK$AXAgUxݶ.)jDiLN :֐eA<]ԈNvۉ|\)t ub:%ł!C d[d>_&S)~3 I&J dvv蹱m0 =+ݞ#2b0eIANJ0Ҽ \iL PUC 1,U8!9ya&u^FU2) Scw& t/v>\A.-C!ĚO* o˚ $Zd ν6TO߯+ǢƼIY+}| '<Մ|\DF??Mڔ=ZVIL5˯Wk%tP8o'[tc von ;µ ƒ {Az` d0=~3uY3o.!y|RYWI73Jc] ƟAFݘw/id`T^܈祲p4z:2{CC?2ul*2ZjDNZ&\z{IOeӻHNSFgtr, OM֥b]yU@>W/kfw eB*qW@ %G8ZbE~bG@-v<b09+SbiI b >%e~9s-6#3$/۪{^t(m X@Hח-%w %\/u՗$J'U"4އ_/n5YEPvlb A8kkV>ݼWn@o)vz?k>qJ<x?m9eP.]@+NG dC\3@Rx6^/|u2$#7uaIlEDϏ^(Od7x󄱲 $<]$䡺o=xLMH j&Ʃ6=aS@!3!v%h  ~a ۋ̮Kփh W 7Xzu8u*0xzA~$~O-b1 ?"t$@[t3ܝ*1NN)u4X.H!pDy䃭N$_ߍI 5s(턪+2ex>tԒm'$!F|3Nbz]nH,ߟܸG^t5 9{ɍ y~'ɰ׆wέZU]Lfc[մjzܥb乫T!ԃ52|U.7Ix Vò^r.Vڧ_td}NdψѰr?̐~V-k'^|m$NWPv*"@#(oF"qd .NC ٱjKj9HcǚF05QhUR Z'h%/;E> /pČ/ų~޾V>]-O:G9}n{̜-C*6mGVvEAyބx*=,{WϧYe@jOI$l D .ʠUwc/\ !Awo{wA߁=O \2qD>?^#oY6!;. ^9r's&5;1SeRשVzY{TA\,qr\I\>HBx=3r*2֖)F£R3@< (qؚp¬vU< s:ڧ[¾'C(^y!O/]P|!0 4eHE/J MT\ץ=h#8l~^=ׅ[WJ&egt*6OSO@Rru)?*5Oh+dwtk9@_/sʎnE$?` eŶz:> ˞nE:e[eΤLydQb^u&\yЗ1ׯs?@gALsfBHg!׆aV%M*ɒ뫐:/%ߗSӝXuqZH"?ڴ@e Ga=XH 7!r:,A &He*idGZo2*{^ v.t^fD 闇lz ɤ߯U@ax!N̽'SL!{d*d/]rﰊ#ӂA  m26t 4Œ(rAmԍW3< ͕r?'D$7+UfLΒʰA0ĖL3I=ыJ}qÚe r 3ݥYX4 ^m]h|A0_^ixX#r "F1^)D>5pwˉ0}}Q;}mHa!vsSc41=S٘*%>F 36}牖CGbN]YH\a)W9ǟOTZ>qsKCd[d?"=nA<:|C oCМ9u%8=`R6/'OT? (l=M= ="+Oo~M퓌_tLA~d퟈?ȪN,sѐPJx{.|?B27Љ&ἺGNJO"ZQ1{shF74EROˆO 0?pf(vGɾ^z?B~ųHQ7# 2= ^(gN?]fbIdY8 #%ˮ ɡuKsĚ RI~x -V4U'޼m W*<1[J/6hWd;^%cO-Y@! Z&ES:E$L ]eaI<;k[zrLVm9PoKz9GNËrW+0 HŅRqn 8:֟d}auKI+,1)ϖۑiT\5A'tb(]NN{@ɢ<^C$HЛNUʹ*!yA$W7 Jֻ6zp64 u?F"gM>9+E^G r뮞|O*|&"l_}rSeLFc L?}Ŝ ZUU[jBqMP7]3[&JA =JpXw+?rAVnq9;"4T}ɵR ~9S xUrkޚGpf,(x*Dǰ,g. o (;$h65Li2ֶ>׿;bEy?mG&Y:31 M9BK Cyߋ03mǃ[.X"Vcf~(1+xz㸭D;4ɤaMQ$vxrM0եeD?vO')W~K5`}|P^T|R]<i9TŤ~GX6:uqN%@RifУveB<Ngޗ,d巽U:vRN_u , 퓗&Kg^r: @OKi-yctl]0>c= TZu4u]]%'If<} ᳇΀H|W@'8Yp42s0B`M3E>us씚vL{;u"/X 's 'H Eϴ3eY47OfLȔ{]Qo߳=|n*auW$ !oSG 6 WcBc!yP/Nko ЗPC  T||Zu֨p|U&*z;'I.ydd\D·1Rd8l=T KC ,=8']}s-s^bp˻JPvޅ2,:!x4׮[/\a~˗ehSzYYbNM'kϿՋS[ӠBGM(](y.C##,c^#%F >%ȐCog]5''I T*KggʶCujx`ձ ~xi# Esj)< E^~c-C~5/9eזW?&'5~/.!pӽ)AN'U#lee-ב[ۧ 1wO2;cֶOiEN 瑱:ҵ-ـŜf)R"l򾠐w:pח/c+[V^U$nguO&ƌ<"RճM}֮=kz: 3n9x4566M L+^_X6Y8V6=|G1,Mwrb@$R.x0>D^O= -A( jR܋嶴>&) 2om ֽ:Z/=kU`Ӈcؕ;&[de\ɟݺN{Cڰ`b7Gonq&`tWJJmb3 ꨚlf| XU$EI;[ʷQʶ#+Vh`|\GrLYǪVDN?%/ƋaaGCϨQt\6c_7 +UfLLez,܁G.6"܄i7%5gbCɋndwHɑ7`}'&yqXH“jᤎBp:~%OǂRRs@'~+2Y^ˁsKPMWȕ]A3_Ol\*GŘxZ0Ѭ V#8bm__#EfM@_\G>_SSq)-9ku%O>D nY\) I?\6u--!ء6,1\y;eI$S^pKg׍:}J!hVB]mm5CuۮLVO^<~_Y2/xAzÝUӨ69"TUg)XB#[r4 `;vêrdc|A8痍 8;"exN(ɤ 1,,E'M$iVJ{rԓNƙ1WE)Rd1x?;0X4=^VZi7ȟ< 痢s |R.n3x><%,&@f~CrNpC=H%tkx2Ȏ!c_w 3ovfN䛿)ЧFaހhf7. 2!}BЛ0lj+{ʱץJʛx:YVY8!A=a2$ O'ox!Y*:@yd[ OI.xH$ vq@:g E7AOAyq祅yy8i)SOB-=-WI&ϖ!=MoXAJCpkhQPKSlÎIzhvҗWo~ u ;u;dq"ļ7WmG4@t)%܁d ZiJYA Pd-l쭎}<C @).KWQ CXi8}D~zR*>GY][p8.vv>OYTzc ?}!z"#(Dx4K%O3r87O^=׫ɡK@Z}s$[$tb=9c fjڝB[}5w >xg)i/ {ɏQ29F}R^z = 5v45Љބlt-A$'.uPԻq&ʐ"ݔtR4 mDt+8ЉJS V:XbOZES5 }j̰ʂ9F]OZFzSy[.dHbt]sӺ+kRe>L| Lꋎڽ URoܝ>[~ MҔ%bX. ż[i%HXOeQv"$!qRcރ,ʕ^>xP+&eVvd dbKXvɒY;z.)S!Ňp@r^bKo C1m&LLBȴz` O'vJk²f_ 9nV.8($_*'\$H.ٯ$wmtT#Z?/xv`x3 `:N}<-W "$`u}"wLTtuQUb_9G`2qT;LG~@4ypA6x2Oy;e PyX>d?^5NcGW{n :ay>jSP=U:_*˗laSC _g{!}2 hZ7jIoR\$-}|aqi|TjO?B #ң-OH1Z p,= >%И(> v狼zKx/b e!= &^O]̓cHSتm >6)_]{?SDKӰ&xeѠL5Ftu@M`YBx:ѶiVG+ˬ.w6xDgW&w], 'YfXX X*^he([QP Eߴӯ|(.bV H]kEŚ=WJʡWYzH9yRn6 MvȢY2j21C #YNP`Q3^VmuJ&gz;^`2 ͫ%R'vH$zKC"膼 'O3>"- o~m:V{}P;TL%aa;z];̚Ǒ<{r,nq=:O#RnNdep&Ly P }y`"k1i8|B'Vl-b|E.t sȼ53{kNp21]tn(ܩ2`䅧Ԇ}u kDnu;]RA'wN .=R zˌ1I+d1 ҰRD&mRo<em&S6]~ p:U_~بB xÈcO]eYrȮK珅;ݵB񹊤;W{MJ)>0 "Bg4,ʪ Z:7$g`Ǭ/{8'2LwdTFGb7 C u^Rt\xAPNtjSxӅ@ GcNr7*vZ0= baNXx!tnY'C s:0\3WXÕe.(茶6Aa^HROxTy ̆v'eP N?xQ g[ "q}ƘNaf9r1:Oг6&x_u|q,jyů%\. 6,lD!),SϽdղI0tEjA'4>m)9G8eXN!nwȂi!C^dN<Hly3M3إ2j<$[rYn t Dﮓe2ax\HfLϰˇ"}ly_ȓK:6Cy-^.#KN.n<_RHo~ɝS,FY7~ tIVGOJ(}~) YZ`1fdRX_Ppm*H)Ju#?f"ǓmoNa/?.W!'ߓZx SFe LqhR8TV.Cܲ`4ԓSF4wR8ґ SnG$ uN@vt®Jк L'4:,Sڵrp<!c5k8a$Z@T`N @ISkKuX5 GOh[p,dÅx Px^kP0YO '0}0_섾}["\坍Nޗ4[q:H ۰%!| i<|\K d ҽ #o,z,(㆘ΊBȐ@IDAT7ؖ rb;n$܀0=W[gA"qN@AMo(c[>m$VY'wлh60İ@/P)u4w(iH%j h0&T)%+m&_9Ib IpasI_CY.&WSnוxIr0z\`?I-jOnTYrh'2ut`KI= `y̟d;}Y<+]1j>c=oBB$Ic쇪Tq2$OtlkR~.[Ӟ3,%菬lMق~Uo4^ԮѻmDd=Z:7.0*~p~ 8Bc! <^Cx)&6$1..tqH `VNA'Z!v~x'B^[W~ŭsR얃鞹*1uE"2bIE@>9薏xJ#A 絼} z#76^jǼm&&GIi eX4.6İ -AKO!J:V4`)$noHjUQIem*fEe\)kQ˒? 5ٞHپFljƆC=&qA=$W6ϟhCOlmac| k^,qa\W8 \U7&*}xFFfM 'P2KG˜Ii#iO ys"Yg fuk[Jiz\()HS0 0tLn?yk[@Ztsc&, J)8-vX{vT:qJ_WOrL iցY*Mtq&l6E$^re)>^Mk ̝F;eMi$~1)bWs:`eG˹Y"@V=s]nolTI"][T B= lxH(Mأt4 h6o;v?uFh׺0̖[ Xr"Pe>)oei9^A PlNu殫oW BGI2]H6< L6ٖ!몤P1}bΛ=<5ҽMvޫE-7/B zn-bX7ZH5ML5(,Y! V-/I~ Xio,)> %0wʹ+N|qmݦN*p5V-}rX jb:.dE{a= ؅*bȘ.υ~dPxk+ vGwں?cxW U}>z{q:wdk[}DU~dltJ 5uvLCd#,s5H Zfq#hDz:¹\#3Ƥ k^7 :tS۠PA9 O0ljj y=SV*#"Gd@$ iOHxQK7 {.!$]E?p'=r`L~PX!႖joO;ukfjLyṸ=!YJvG4dtC%$vr7F,䝅G]ռlga^l )L6A>|J{vԳOWՎ})A }yuLSAE# kfd;jՀ t+uD [%;A*V/*r?͕o=_C.;,;*KKQ/>թ㖀)S#[ gu> K~d٨+A0L$?{%,W:p"O/5"IVGOcA w?+Kaaζ"n,,q)7X';h1p!|^'餕}@4y|q;?Cr ^^C:r)tb#kj(.f|ҬqQ[Mgmrl2srd723İ@{-9@.=NWPy(1mOKjET0DW <)0#Nͮ}ʹcG8Yy7^O|ptRX3C9Fh qZ'a N.rNx6wšPjhobHfrWYUʇ@9v}s)}2p]^Sq{ͥJzE :« =}r2;Mf6(MTaIS[9e~jiG0<6}WPSGM2dրcO\9_J_0|~)rd])$ @.3ve(~lu,dgW tidʕ#שkGk¨Ly31/p:~h7@jN.>?)MY*'qdcK6$/'GYq:ar ܲqoz=""tNP%!M5rB"Cx4.#!w4!Z L*V WQۨ<.\G.&L`rMy/aF0 gg.@GHSe^H~M%oF($Y>WI|E%moHEO< nklaTTIquVحMнRo] DtUBe3sP> 9-]P]ħA߀g@Z2f`||38,`O-B(;X% ,qr9'mӸrtVZ6.#٢.b i>V(7G\:ˏZF/?'JU_O/EaFdO,bX`YCjD?cI 5g\IyALz|Ȫ0?Ju,0ׯmC걒UxYeW6q#$8 3+NKץ J(LY6'C FPy%DA'p93CLjY2&SӼI@v= Pʠ'qb tW:өN Ӻ\Ĉ*wh2:apF2"!w!MmMyY028Nz9Lj[p9Cv}kbAvHR(]l\`bH.Dri-5Rh|{Z8vVxÓ~o>Q'+?qvBbW'v"T?)O0l*srh'`HO`T[/BAX>>/P6l‰,3|#7^z Fd`0 >茶aub ̖*KA;OtKixfxj% E{ d , Cbquw_&_\F3,$X0X~3 L2uY6AMN'eOf+Hx)!Ky̖~xU 6R+Ś,$΋RrU)9@KM@s>BrwU*A]:a>q:!nqF[?  q<4vx<~amigbЉڠlAD~@'6Wt ՈIsI}} v/cř 2|r ;][(fz =g,W ^&~ӛY@?EȺ )V LŃ57ۦRt/E{XS<9ɰ\+ahվ𑢁Jq|~Z}*e%펟̗)2ђ4o'_R*ۥ~/<0loB =w~  5BP לX쨸crtb0d!+K&H)eMW:a6Z#^Y%t"h1fH5)rɨ2t~i@"Nɷ 5k8g+,@ `u >?In7LdHMՍG +ER]Cj<Ft_8x#j|?&fٍgnU ,/ UNlٙ.T\ gt5J‘+q b- 3\؃ĖXe9{w˻1QQv0?gg `A/|=]i< TPPԪDBiWxN?xQ>T/7lqM3d|^,io=J@HnFVhYqǨ}pM|bx:)E^kS*30a۶mb_rn[6sUpφr٘ Nг"2vkkk(xao ZxU?> sot BpZ84xUIU\ж=||zEܢK#@jngY~"fCz_sjXt}d2-yq} X1;$7.71&;Rw,; ,3'8T댱)bG8޻qp/w'V%@r?^"q֍[ KuȎ@踺!t czFATI<#*c`2x",YA5j\ԇDKAn̟-/Fv~oHXjWn A g>}K #S9.+FQB!"q<.B68fB Z~>&D{%c„"f<"@wxz9Ғ ɑ~aHL~Z %@Fr/MЎE~t[6mi|ץ;jN Q#9 1].}jiar Ln#&KSfMH>zV}Cm6͖#ȮCNK?C-xhYuJE^bvk$}@o'zFT80PfF'VK  nǝB]yT_0( K2~RYc{ `[[E!6~l@+VݿADEf=9r:At p.Ó, ` cՃƯ<Òojd< 3eT 0@o}dO<|*.Ra;?r0Rv0l~:A|gvp]fH T"L< !p73,'"|Sw GٳY j!T Z (o&Mu""i\bVT"Wxr" kK|~#QL4eǑc4y]WS>f9L`X-'f[7éG~[9SF*'hF;973'fǘy)T(i~B]0| )tW=nEtZP L/Ŭ]M-LWszZ))^;T-ȚqߠDqׁ"nبRhuK Iկ|dw5#~ F0<~>S ^ .T?+ E E;Rdǘ\س04z07X̨BW[ 0jTydI%=X?q!Gq:q50*Z#?}L wɖCy׎z?Q䑩Hݞ#/~coKqK8cbB_=z^CfvNƘJǐ=AyokBH\k۶='0ϼר1{fG"r k?R++=8ax 7O'9{%B#y?^!صt\ x<}pn`Nnr3A'x_MpqTV:ClxB> Ndd끿7,cXnR B_r*v񡇋[&t)Tٻsdmtjb4I\ W'k)~$n]ADzNLLX%{Coiw@ә^9qLnSY ^At쫩lҰh -C) OA7y* (_x嗆\cN6UcvNpkl_oO 2gK <2H_HG(8':M_B wƧ kCwAaHZ4'ʀ$6qSw  $va>A4wguHuuV ^6/p *A.`T}\X6Gu{g=g91Yy,֏U/q_};֓z1FSAZǐЖF|)cx1'X=F4 ꨂe'Qc3eLY;{8e>ѾZ5ww!ڝr g&]ovxIe3W#Z@ydCvȹ$~2љ >x>$9.(ݖ m棱֎eil^o^`߬-osM|+%ӟEڅ@S18pֹZ.%92I>g\]/0y.Kq4.*Gg ] (Ͳ=ɻ/&.=B6 "A%Ug 4ȆT!wFG{Ԡ\YStG K :x2BX;33lp~4GTi2rSatydb*cW{{OƿXזܶFVoKa*vݺgNˠOaQ҃ga$@ADd%_IU>+"a P.roCz{|0qrpp{hD*Ƞddw!Q¾2l0U|:xoZz=iJﹿ^F|ywe5?O3 'E@ǥ644]XK{T555RQA-Ͷ&swȖ~/'ׯpK{%H9i2 pZ4~HDlCv8 ~)Gf0!ܪѬI@I_iP[{e~\UԲ\?x ]2)k|+\ICcv&g-$DO;dc*\."}SgsJ5vJpm,T̾E\KmRl}ePrt X 堕IлGoCs ڱBhHR,ЩP>g'93UJY!P&^t8J Mk ė}߳{)~|QNNFEߎ_b+*=|=E`ٳRUU>G 8s̀ΐaމ=┌Jt5 o<twCVla ^)9wLKK9,;>;AP 'Umi2wrl?oGKc6I׾#Ӌ@'w]G]N,m9TKl&'YeTFޟ'OZz$amY#ztb~&z&.sc-޻R ;&p 6si\T^܈;lt|LX-- ՝eVeEpx!HHq>5KFfc"N,\""ma_Ӿ:g8W\^ t/1vCAà>9"bڍ)^-O'xZuq [me%q i'|J &xU@u4|muj*t-NșzO&-  +0x2Ef #3e jO,d$n%L2Vݖ/#?mx /1+ʎK ^1:c.W;ڐ vn4H sȐW(usp& WoA_yJΌ!߆r82(AZ0:2(NM$"RHQ]vǽ)ٔnk:%mYVBuv;H{3 Q8޼z߭sݼK3FYQ{9(8[*%\;(sÅ΅_޾v ;c~/ Hu5MRma"v 8_OIeš}5"UtK`SVfɴ 4ԲsJ"D$nb@ΒY0")E2[UZ֮<[e{c:wGX 6L%~+A&zM|PzNJؑ8VL5V\ 1V2GN'ȕwFg/B濂+k1D:AUS`'=*hΒ) :!9ͮ),m dw#ח8G"x7, ĠH)nuy"쪲ۦV7Vo%l9jr"#@>$R8B,_%ތdǵe.Z#+mNVa+7; U0;n r^$@ KcWx'e35ԍ2[6}Pl!Jkh sNE +.oWE7S!6'N!q|27Dh_ʗ ϒ|8V枯,u_XdᴕO j#x W+lXv`KOJkٹ8/? Z]\ mUOLL&y%Coiy) n4D -IDmuNIzn~ tJK",\8 mmQ>OfKFII&;N[Kw62+r߇A& YeF Nnߟy _mtKүVʠJ}/ؘ9_7]p'⏽Ug?[ հL O"^ڀ>R>.쪷ڭY8\ee,"}uΤFNP.)(ţ4$Sw#Kp"|3>Pa+V2! ]Vclh& 8G3''C4@BJѸOFIQ-%YvUo>(ng^Qh.cyTg⭐zM6ZR]TU[]1Mb}Ō+t^κeڶin ?$agtL׾pn.@IDATW o_Vk_YdSڡ+DA>Y<݇9~Z3%Vt:}>pH{,tG;ZѩNyHIӓũ6S+X&vAՆ ?! hU;[5˴{~4tT{fV$Vtνo@ ܊:,dz NB @BlQwmɘ H'eY?.sBV tdȬTMϝ3x ;hr80-jwJE dO=gϽyƶ|PHlpKbQF&kRmT>)Ɇb>'Z 0P!tWFrD\P6(c%-btVo*-v3yT+ bl.D^gR@?}kI#,-+,iA O(̯} |H78lY) -3zR\m/SVX!~P6l<*Lڊ $"ЊVpIg G{ꘂG0i_m$OJȃ3JD֍nF|& Yi?RH(_pQ N9a+/џK%R$\b DȧKLvhĬ`cQq#͟TDBrWF/{>}|Zx6-{9gV5Mp+T3n Lt >[W٫{T2 lp~FHlJ2 gw'AI-IKpɂ:{bڲ"C Vs9m6LTBŽ^]i> ֫$hqn qM'NGUkmbъ"\I<-+**j"d'%]A'[A@%Hvt}|uv#tϷ=~<̂NȱmYSXu[chCXQ(]CIv2HE7w,\EB &9;`H hJ5|R!Np ]f:Rfݬ#i?+XNNg g0)rZ2빗&dZMN"oH;ފX6xCijj#jAeEC>5kyq'3.rGXN~m=Xozi1WmeL_ Ui}ީsq8Yt|dD%hӝKy+IHN߈UN #QOQRq>uހpzeM &_MHF8:4;2ьSΈxRG_v>_>*3g<rYΛu8kJ34@k(Ge$IHhJ^i Kiv3B4y0X." rE$NM&}d+⃒[V"dH9,:h=۹-AAyĈ|^U_Mz$9F&A2tN6yQ$SUgv(Bxi3>.mhl/=X<&WRXXsIQNA~ q_T<}^T ^[m)ĕ;Zʣ%é͍+$"L ]?AYZfwb S7 ~:7֗gSbc2HZgYe#CDӀz&i8݊cкJ˚x'M%eSxʏ>q$ظ?}'0k>v']p=b#aKf7Z:ZWZY1`F}6{O0t+a8}[j}/qW^k7~;U؅KG9}b%fcRDb$b V,g[쏫N?6ޫ;;owazI6 D"6+tZAXФ$r:/|O| ҩOKbn7iCyƅҒ $xJiɰ.Ӟ֛\齡J_fD-͝L4xY+Bd{FBI+XĞ|唭X`gSsf [0(|0I>}@FS%ֈB#>&k0ﯲܼrOUȪlNeN$) +fpW28 UTH! ="!,yŢZ]-&m+AVp~rxckpDBR@?`Ha٩T|*4qtՄ:N* plɖHq趭&Hsoi0={oML-f=/UťV%p)5O]ZJ_*C_'}ϥ>>Ȧ@#eK&պ͕U[Jb4h3npol(aA'5Z8wZomj?RR?K~J|hńF[eŹ,}č q0_`Bgo7kIK;'DsǠך4|qԀw4H'!~ ZNm{YSg14+2+AG01jkA>uY}t⣖ ++r:15Y<8\~+w^G0+UW֛4DKSB$枮}m2۱tiFp: V`  dx4'O;cI)1p0 -L;]T@$(-pD…SN#t4lP`e,kU6*ph:E 999|v~Dt{A䑂GyǽmkIZK"D4IIdINz=D :d6J_\_85ҒgqǺ}ӥ r` 'q\*NM{7HDz Dȧ^ς>`J\Ftμ*µ^G|:ga~bY.%8SS6nD:&HEnXc;ֆB셔3eSa{{z'Ϛ]?gvK3*uR 1uT듒aĭ6qxx\L;!{V[[ '>8hxs=H'>Q1;i;\}-VSZd+ō̎u^ǓK# п^XYd1n.$8MSaWMjtn{ K04ouI+EWf_7!ͅ}4Hp_MHyu!ɃMMee nG݇+v7p #NZ7Q6X%*ߎrI?etOp-Ҳ N _u5vۯϵe+X>hI$]-6>t-.Նe5)4ܯ#OzoM"U?UJ+=q ^n0?yG>׹䖋FЫ"':Zo nhN6֓!!sH)@q?v~r$ _"CL4/kHm__Cl AvrZbvP(L8!޻vÇVTJJC Dwǥ%9.Mh:q3L+-2; l@X1]'ʭ=?|W%=}$&\UT$\A)!6u 4Mb[[WF JF 0|?UE`3C1yb-yF[a :ˈà[YOdfenj)CT.䑅1aw8#ȧ~( ac'!ak!pIh 8'>vP[<7RS: 'T{&&~xD&B,Giwh:s%5A"T":[ M+>#?π_> $\v Wl РD'KA7KA6?`-~W0#"-06K㎸E]í+pLb*ɘ g'H$md\Ԑ!C)UD(p:ySX =rj<8,E6IhItLۓQOZ(KJّp@|RrcߩG4Z6ՅsIۂ5P_^Sj_xh8gchpi\h]qh#,fW4VTFF\ )@uӬD{yUoh9ƙS.]~|T{2tRy=z՟e&' $ 2qdݷ8bYg+J"5l?~d oM?pۧ@%ӑ&t]I iIv$ysK(4VF| WYI,޼G(x dӵkv$P^(bhl*iq_[4(O2L"N'm&TL?%Bk[YZ*ǝpݜ?=+T;#7MRB)ǫl/L{vW5j֦u$%U`%A_GZ[_kkPN+b'Fg,F PIMj,ck5 p1P_S ~c/ 9-Lnni n5*ncKhE;ɣX%@2C$Ir"LN_@R"QMq*HMԛAGqWPp;Ei: Q|?z诠iv=|HGvb &@R2O,NBP^Paڄ1 q>eRFk+7E;Kƍ'A>Xbx5%>6ruVT<6fp#2gf´1Q1g0O݂|fTGB-]? w_pvoD7t#O"Z=nszDȑx{v_WOXMUl@QHKg%rt8T8ݞ\;Ƀ|3Z_l5f v/Wi1iޜnٻB7q>P3il4p>$l> D:iiu%7%U#c,}$#xhw:۸2{JH>=AT޿^J3=U}%:NX^1ar%A7z= Ɋǡv\gvH'Ie5>Ь}yH g1I>0:eY]h'=e_j䣩Ls5W^4yXGα3-"kvIl'Q@6Bc qkOSDg|.*bccneBZO~3\{%@HQIvDR@҂כbʅdNͤinuǴ-]]֊jV1ZUYy1;~ : "t5-R/Ë[c-Z ^l%ɶe*++mO4IװhϪηuRi¦U^+\2ЀP-?.MmRL"Dڇ3[?Sh>.NF}a~eg-HO|QqG+lŎXËqx^_8- h~X{iCfEa#E&vѐv+vtOjH\~:$Ģ9nLX iI4& B^Pfo/]Vn_jw_h7r+O(=vmѮ|D:'<Ϯ@~%: "4 y@mI:il0db,4 ]?uHJ-3$HLڍO@xmev9eJfC4m`ظ5_Ļn ')}Gzx5C.%@&x '압t±g-M۲E6v8jQB hRt-AJIIMOB4콚dz9 HkigيdW'հ${[+ttO/A?6--q&ߚwmxC# L&b7lz/Ur@|2EDH/Ԛt̤9h^'%a&}uۓ8= ddqIn;S $>[y)s8hB,НJs羲7R?%⪶Ku˵cbHPzFY46VLYw,iHtDS.Q8>Aph4zԓ99vdey+R_GB_J:X@*Yayi jC? D71~?4) ,;y SQ7ߎf\UϽ'2(4c^LcFM%9j-GF&p:Ч4y/&$畍,*oTPR3ɺue㈳FtW!'t]vabj'Nbi@|R"U ijj$h^,И1owܐjϼYuVE'l.gU{1!Z*40K2>Wj]UmQ Dndo`Z oz۲n"yí݊qI,~v{eeY?Jtg}L_\Wg? aejZv/߫ >1*䋁h:gv P4PAL9A^:h>I[&pke&/n W" SvѬ\T7]V߃sfXՈ(kz*4jP05MIOѾD% ē#eEE~t>DXDEXz8TVTS1-?J0 |-` h1ٔϲAIs-8MCvIuyqGm,шA{9&"U.-rONl? KGOH̙U[W5Jt(!e989ATIebpQ" ΜGk`/hJWD~ O*;c6rv=留,Uo أKYM$B-u8 ENƽ Nˣ Ꮡ%u8q2C$.<^LJF>td{Tuuq{ڼNw4..o@K^XUl{~dH 'Mi_ aUjom,u '"uAU}4`DG:-Ey6L'赬F-AWI5ڶ^ vt"JBO#b ۪0'UWI+i '.xsot2|=c*61>GiGGm7`&s*~JUOY&Ue8Y\~aA2F)m٠2fO=WY8F=dJ;S̺D}0'\Ipfg[z`.Ej'6UԦ+`gK 5`/6#(QD( džMlE\ &A,HRj:~TG)|9jjXW铬N`?ej@/e H6hL'@S_юĶS-#أw8К([-fi{,K/J=ȭ&Ov חWGf\',/6^YhUcҴ9z1W${(1edao mG!G_>k?yNSu}[,;gabge|< ˈE#t pfWhQVUg'ŽP\><;u|c%÷ʆVCS?ӤzwNh_)8寕P6͂ݘl3& 14@`\I=DJfHiPnUMՁ`@}50*IóРt  θmf]DIU67.yqp庰۴{ [:W6?r q Q+v)zgs#q'tJ{|F K`;fA7rZ֞=\]A;RS' M3lPzױzNq"j~H@SF8.&݆$I]MSEKf}&-}RHͤS|\&נ$ !PNZTշ~PݖdPg pt&|v ƃ1@:' 2Ai*YJRNǴ~|t "XeƄ 1b%&&چ ĉW{ߕlФoiE#.|Ssy!T6wm*œL}s!NTX\:HLHb'ɟ 4U#g8Btj W rQYgůpE\_+׋ aD~k^tW߭t"Q^:z[5 ",W'BrrKJJrY\ē(P8RԾ4t\JmZP.ļHm͘y͝;mٲevܹ+mDM Dȧ~U-:#_FYo/v?C;;!%ͳ6aDpu5}F,w.}Uݮ`MD)2h.2Fd1qȏKi(V#RˬMAft?co0S¾Zo܈5؎# N*| =;5ʦI>5{s?I &x6{Ғ\\w - _ %XXMEdc0oMd#Ls<8?%fk|Gb6=$f_-)Az\WARlVe/*M{XMG(?oN Ai4hcz,kA:]\O.nePY7*SqfNA`rŒOo(#@G#K)C~I ~_0(""8ީ\ΠtRwZA9r/ (=Za?*מ2]T=7hhBJx^p:8ֲ01g(o# 6ehˉciT򮷃2JAI/ئ}"%'ca:| - ;5[0w-$P;#I-R8@[*N*B\g`< }Ϋp}o>-+q!ZVXF}ʥț B7u&0L"ZN򟖄6VLO vY4eALXmcbeUh 5R} rb%I5lE.ѲdP#DR$KP$HA[KI!d&T^Gr %7.yWg!Ā-?ߦL¤HmڴɊӘxm*{EI5lIunj$v43$M4#\_r^Z]jA!NB5bmԀ݊囤|Oj3SA|cv.g4g~m}{nmi:/@2wCA)²:]D/dTW+m⏂`J\Fw? z>{:kHDɀX#e%ȫvp7(wkз)g,IǡxVsNyg/zťUeX%ihfĠω(!&ҩ*#>6 ʀՠc,0H:r-كH[!Fi:_TopƆRFmG (4ncQJ1w("_3]&cO]zCtwRiW"e>HE"-[]`{Wb:~~w/PD$|ZX9>N>A?i2Ԅ16mb&OHb$*3ffEHPnQ#,|&t"X)tX04S}*"*ІT,~U悼 S>[K!d&ךd zz[AʿM8愶jJ_Z僠2mP  ~ 9j p07(WlM16$Ve+ԩ ԗk4psS-Kp5c-.*FCOIߥOl@dɛVXH6 fDצ]GH#mug'IS b!µt=-rc꼞%)_3|SnUJ@}… rOVC9Fa%s{4" J5IJG<Ѭqcx ^\l5 1?>(u)|M& Δd]bvؒg"kx}5Ax+w48"i\K&yF!i|>}X{sn uƱsʳ~l9[~i5tmcw4L:AȝL &Q2T[;W Çѽw++1bb6)_E/,w uMZD]=QS 7}.HȺ h H' 'Y~en $sL:],Z#|T؛8?ڕVy\~ 6I"\n``D56N/@{H aNoquAP1g]]pAHϾ$F3LWOo?a85\?` xWHK@! &Ի5R9%,(.8v:9B*{D!5q,fC,TzZ|LIvtrX TW)?, ԍ+J r~87xM4 q>\P/ )F#")ीZיP皽v$I``{䞧AWb;K[4\w g(+\IKj?#bk\YBŹ;_mF{6B*a/M_2#ڞDZo}uVTȰ8SvX οǮc|'KLٺ.>v%J#e<,8N^esHvI}W`v[E:dAIy}mma"M'Xi0f>wOC=r.ƌQVw74 EJg>v+wl9|ZNiq 'U-E)=T riϩN/zKg74ZDҭ@+N{5IPWbԦrB;oP/y~_xjnP.;wіQ_ 2Sh~GYIIGNOu+iHF6.ߋQ"$l}#`^3(&=+lVyJ'afpJ@TS^krKJgy9iS‡vt\墎kTEBԫ⤪#aUnERc8pYy\+*߶2Jk]sҩض- ȷ DM8JKKMOGLXmޔxVDɵ˕| DȧONmn: 1ɟllD$^lN+i0mo#\x>4咜H5))~j><+rF]*/j~q64'mvو'E>m1|Jd¿?qWsxju1O)Bi;U[ﮟYUiAlT$U59=3h|w60b;$C43/ZCqܥsS:҉k1j6 EXz sA}HGP 5JTHųNVzd뭁=3e+Fdj{RS`:)-ÂW@d5< `)hN*24Krrr$)ு ÃKpMP0 ?>B6םaۼr4=o1|;TT :ڰTwTD;o$+ 0 |T'BeMq"PT%wj]g%Kp HIuk;TF0< 9Љ ^D8ѥwlDCTHWU@IDAT?mc`jߨD]ONN+}`yE3 N=͛T-\K6\|t!42?SN3#Di`EF_t]~!S Rf3l0GԸq㬨V\,=V-,N2H+--_5 S J O|TS@jdSˣc!hXZ<ml\4*MVXsi@|?~NGKC呛Yv}}MZ]KY %_8ަi4*[a(1gKg@>/[h4o`hX·ӷٮnZNAiqv/N$|;QZTXkJf_*"9URf4{!X_.Nd#sZZN)uT3i '` ;/jL? $J-6nvV[(tfBa, 7I[uV@:Vj~K~z0f$\j0L2d#/aHA1| H ]ț-ڻ'{CB'Ih'1+'Nد=a%%5SJ@uAĢRꂞ'2J!U@!%Vr%"$,vF_rdTx-S 8 Nm..JߤAfDwL)?fl^κ+,j48>_+/.܊ ևW#@46MQкTKX6-ڽ$6No jl G4ci$`uMs;o~]i^)#ċ<Op|VٳǶmfgϞE+ u̸p$ᯭ9esfJ 9(O|<.1֪cGvyU>yONI^ݵ$B+-M|VZ8#[bSǠ,[GZq!Wl)YCU UQ&p3@%PN H5+Ip:N <'KE8 NcNZVX>+ 3;jjP<Bw;F&$I~ȑ&^jɓ'cj=o `7PPs)9k 5SWGI*dXHx&l{c)g^Z6++Z?~s^VVL?`"E>@80IXe0dѝ̦C÷0NJR$DKpҪ"ؼ~78W#Mf !~R9oᚄkqKnN^x~o#g} Kr ȽB JOm(xw6'n X}-)ۻբ9;VrfO2pMiv[PJ4^'֝"Hb#ʝO]+Yg.OOd4,aQ&"LUF>bJ[^\Qm{KҊK{3,@/ ρ;:HZt~"-#<Í9r{gc &!Y-g)f($<<5.D:55k+A~W6LѾh&Ĺ(Mt%+ce& zB2~_"ɛG|I3!B:|r|BZ =zZo&jpB^{3Z?*hM$ӱcl֭P :E%Ș?ZiEO&1cbrUaa[=[K8dh2((>"  :"Ӏ.JҦjԆHӞRu0ͮ*I dpF f:{|k1ۊGl5] njCKd~We0ݑ߷ы,1&{?T 91#4Tt7ɳkËbOU.#Bb'9fpDM:(:F۲^b;9: *`Tp WI|& #Y~vlNY6Ӎ"*ISoف{8^ ~`" $HiԨQ6fLH'm%G2N>48]6q[iQ岚Tv/GP?kDM~d=qQRӎ_J$DR;S@Lv|,[r?|G$\)_MO2T}cՐ$Ul+.MlL4,)6:?>It k~UE;|%D[z +陛6mrT"fLJf\dA<&B,Bx'&y]3S B> 흏K)lxhgEvlT|8;P\~U20*([*leuG*|.N*VVuYE$аh>cn|9I2d_>೒Ȇ٩=: թ)H;f$6wJ|p4%NP6j7=;sB\+狐Ftjh"DtO锌bbI\ù5JV+*mMVr|MJ2<4i5MOL3m&|W[./^:u%*¯SM4'xT; z0p7qH:EZ]eСN[֥P"wL5Bx#$iEË5PP[w**" YU}_j$X?cr/U(H@OpV'EC--a*4$ԃ zm$DRR㰂LOD8ՑN h_nGSIҪ 'Q/hdh8Vέb"V|KLMMZP"\QQx(IIDYX\$c~v^AA<$9# {ѣG9sm谡̎oԎ;ߨ#͚lY Tx1z\Ëo -.xRLSN\6DKHh:.HI;UJy 2tM'}$%y5A6_" GCݡ6dX}l3fZ%9]ng6 ^#MCzPoCn'RĄ (fӦM>}5#t/:o&?I5-;;ۄYL$Q~xZb6T|s11xx8~:iUqQǦYaݷc,b7ELma} <ܦkuC)f-+"gG}B\j9.}[^YˆAc% \(`i )8ZN z?f=W4ȉLl>ڵt=~2H'4M`JixjGCƎp'W&Ȃ)6Rq.KO.]ð2 Oq0?چ7<Œ6@%Xc SyН+)-x>0&FƝtz@j14gr}ClzbC-)!ӷ׃|v&R҆mN fN\7v ^8ՒsE?g ۾d.]OXk/>Ya$0LoG~LbY9'=TWHcDܷ8A]IbA-a˃J7roJAMpxJ@e/ 3D}A:ye-fbVԇ{+SI<5YOpk"@"J  % x=2@v =΁tzoO"0Dw%دöp9$+~ RQYY\9qzBH@!1vI_G"fy~MU>UVcc9hx7}]@{bh@]R]y -$t ݟkƤjA )bhЀkP~Kc^&vĔ-{_*9D xB 1>%;8QN␜jI'Yj&/9s9cN5lX >Q>_ ̘4|pOlS6QFFxb0Ep]ُ-iZbT)EI<6I^7Pt^Sχ gY2I3O!.LQG]mCr8Iv^~5ù];bRݻ0^+W^,eWIō2h';} $88EIץ[q/Iցg.ȊttaMGWfèP(+7S :8CP{7DO!vgIeWyi<0_~F?|'ZS*j1xX@JQ 5ڞQ`sU:M%Ī8Mu-/(Re=RlH 80%p=m/zݰ:Dj4I#@Mp'=MZ'[+t =^ }ÞfBu潶gii;Ʈxʒ=x?UCݥ"TDx;Isw`RUtDyԷuWt 5R< UQ60~0r\j8zTӮ~w4Hҽiw?^ " K~k9&W5p3m Hz3 $„ ٳg,]?&dx <)t4X1#K;Q#XA 8P>uFenC Vxѽl*eL2q+T[`~(hw{NUŚ巯W+Y>UmhO산=etu~Zf&ݏTնu,l|\tድr:O}-D|ڥ'ZVt x1b0;6ţbًD'3kTL+TX@8އaCǡω.2x:LͺIlv~q!=*BEீA?j61ÝB uLD`w o$19st5H'Igto`"9=>) @pgIX-y KDXi),_rk\6m@%|>Mڶ˜p7*XvVtjg25WAl)I'h ⩳J6΋T p?vk\bL{.b<@}z:XYZ#͖qC}E=aENUjr 0ã!w- 󕗗߲e 5{GVvbjX e -h0+iO0ȧF0R#6Camd#F&:u"fF{ %W_9!u`Hb?me XǙ*Y Ϗ'U=Rw\FCmE18{A~Yt)`C_^~#9bWC<׉davnnC6Į=#*T Np;Ċ<-pѕq/W(xd,wJ6xE/@o>[8 H:_"*W"; 285IFX%3RU= _$؛G"GGwvT=ޭBb(d$|(!άH=B >B{x?X4sYщ,O?%{ q^#wcI'xF n ؘZi6zc%1+̏^_tTݝ1#}Cq5$>3HE)Ǭx `?`iT\\Lb)lOn8ydŒ d6nAe[B;p/C `҇a_PܱcPؼwsۡL  3qpT1aICzIޒ'#7N|hUcR`_CT[G-ƫr[5,˂iVu=ԤXyxsUͯyJg#y@\έ:&Ix>Ȯ&wS`2!9;\?o':ied @x9Ƨbg֭[pY JUfor;Ev'`lHЀA>[d<pꠉh̰E +Nk(`cr(Fl!N\ʉa`F8s4lNm>}H\H&#͢)NyScc\; 5%!ﭷh ๘M.ϕ{~!Z8zm%mLuq86 Q\\MtRʏ|Ζ29zN#Ex02 \%ǪFv8aQG̸Ekw n )ET0[l_~Nh/~`qwИ|=Nn6sqӤG< lCx.*h!c+1:҉^h^wHjl 0RYYם 31.Y+ҬN3f4y~ׇݙmͬɫ3f.|F2TOʔ7z<#@C, iC (ۡeuXSiMdk+k,w2hhЀnԀx eF线ZJ} 1A q9{lLyy9cM{@5Q{z;Nd8@,5rl&LL-q,}۶m*AxdYA*g\إ8!}@ro5jY :b8$P-"m^pkbˎcU241 0T84~ jU짯>' SG1 ޢR]yMI`Ko'.$g>bzp̄z؈.)L1 E@Gz<|JR҉%-=2|,_cCȎl^9xJ*ꚓ/~ zmhL,;h8l T+呉#8P&s`ȺF؇T eY@.8K{I@M!iرc*&ѣ[5teuUU\V k3Mzt!UB Tr=;5|0c4.͌I0{\Mqxi(6{RjTh d WQir5:ڌSE,Hu %`Єt"6CSL0s}Ѽrpd;("ʭnGʞs!T:'/ꅁ:'OF08nh\to[4`nQT%tdLfwvs\ z `HiR4Hx9=Ey,1Hbwm׮ox=) ^ xGx+k2E 9(>7sPtc7I&M$Ng'Wݻwc< #^F#20p4ɱUFրA>sC2nCU\pIعL8~AV:xd*f%dìi'/q˝\ւHvx ˔v6&9՘H,$lw|L` Q|%rz5)rPNz,,gM<բ*=ѳ^iJUի85T{Kƥ;E`M]Y3חʉsBYq0h`P\-7@*F Bmh'b[i[<76t`U!QXT":󵳘R>G AS.SW#ϟǽ ibP]]=1{޵& ѩMyco /Zv'}(w%Ij} j!3sw@&Ƙmd4I,kL 3KVCep|ɱ *? H<5`uR\~ ƫߞԕNϩ8;@*Qp}aEjt:qF`vm+.8=J y?- vEɩ/W $>:U+o#9iVÉ ^>iz`|xH I #A:-r|oNxSO'ߪ(A:e֩`.Ҋ&yN Oo"?],|'kwQ^ hӇ1϶8<֭ia[v>fV֡"#u@<ٸPYws6ZC DYP찌$nOmo¿z'5f`! ^ hO>+]+h ѤRRBS}쌐,fZ0Y8s.qλǏ<5F^-Ŗ@_uniy F 7nh;QQF\E>-l]0DPmɆм:0ez 鯜HVj?ʄ;R:~Do' ^JWJ ěR';`x o;e`rۨwDH/F\v-b:ye f+)鄆;%D4ܳ(ALKjH'G]:hE1dz,³d? \<<׉7[$N&3)摅Sl乞x9"+}n/-0YcXMj!=Ɨ¥^2) v 2xDpawð`e@< Uy?{:SoI4*CdOfҐ50ed`F;s Ca*y _Pxҵa, ^ (⩱H1])bAılSDK;8Ή`w aȡt/L_IHR=NR!N 2{e`~/ CB<&+i)zb9AiI,8sC]21ݢыmgN킰0Uea#? Ń}NA'Lp%NW˛dωr|<uiy -H!`}i(28%x- 8귢Q XObHe nVq(x X0fҭ@& E%in׵#:70:3*[j 4X_UP _?^N DAzXǪYb,WKkrAbv' \W-fl44a ጯlxĘ;bM"$.bԊ3S׈&i=,S]ЀCQc<2%tx}P;s2C6"cyKP n*@ZZݗ6GGlw5Q /h6 Um}&hmW4`O}IGvh<<+ 6ױ '+eX꥽ ]:?T|b}xr@դvRNjؑZHyH.BW$@IDAT%ȗD<dcV z@%'ӎ5]9rJundf|qKd3 ]ҤnHx"ݫ 3$Kaв3aMKz$3 3Η8s|:>ՋFI\k[ k:/4O?՟X; TӐ'KD_7s@}=̻"+p2n+f4iLs4O-rP mϿ>٪F:FeTqA CA WPlVR\†ƫU$L3jp} {~ 8t]#>~\/zJ5̳ARQ._?u"8K6»3mxW!pu2l߈%6s%o~W.xFz1ʃH:MHw {NA%j?j~pXAq\"xqY>GlY4#-_Q!N!=ȌA~}azM`~IЃn' ~W/Mq֨4;C6&g;yFހ؎iCjJH2mF:ᖂPGmV^>z@0RSGF`:e ;*8[L q.)1`O$51Q<,:U=h1^(=ʯ͒k)s\fp{ @6L5qָI̕d<qi)BmI܃o/tfO1ȷ"/' JEJex|qT4@ȷO*s$CN]f_> S)fȐ!tSxwHt 9v:h> [| |ٯjծa;}@,5`O3N@඙&5=9•H,.!b-Z-d򏏧(vHi)홬,ٷo_pf;;QT U;h@h孩eޚfU'4@hϣGYI#qgD$B'z $!Ow"L/_'ڠɘf?TO}>H*z}c p"0ѐ8ěr+k3^-Cg|QÃC@7H: %^wr N'%r7)賦QY]QX C҈UrJ!jdbc䡥 *xJ|jVp.#. oaK^Ξ6x{ՋoޒҞ {'ѻRӀA>gr#sĞ~̀ƀ=Q"?$V*-csRk@`LJ/NLp^S/Iœ;#x+Vq{J[/ ޑs`FgR9&3Xr(@5.%"+f{ޅ.>7hvGN>|B^X`;as< /5h0DݭEP 6̟0圤ӣg ݈]yԥ˽2ʸeШ lEtݔV4ʶÕ^`RHH6@!+[WID4ؓ#G$m2n88R$M/^?CM?D@Wt1|OPt'uQ)**"F?b9 0 %,,g[ wWr`>NUC tY,#3+ 08Vx w m"} )o'~ēFШhlqhDj( 6sy/ڹUIװVS >[Xa*Dڌc-&ؑp[i~ [ HRL挣t Ä_ RW)NrpOe^ &” ,󝒊+8O;𿀹~?#m8ñ?Vn .T>Ď|Pg`[񔗗wU`@I>P3Q]ɵFC;CotLf@tƝQ:"ԑrVY7fufJԠ6d0'c} +1WD&'v=]4[j b!T)C\=  *Ğ`nЈ5#BUEyK eyr p` ݲ DAq v"';:z{)|N^l=EkspN;0<.Vz2NJs/93`v옥bM)@ҩ%gEOh'[ӧI'nWs*fkG7$1lT)!WNf ^E uPEO'vzeE<@\U^Mj?$Ff9u2.녒_Tqqͪs.1xIta| aa#p/ m4%/ lAѷ(9GU* QJ?Qػv0,f {:-- a~ /~  O=B0= 3w4VH4to#~xkz֗-w͠FolZ19M*ȥAe!e`y dlwras `z-̏  +#ٙ;/=cξX<Ե}a#>y!eVhd[1` x8?Xo.wa) 'G_WU?>}ڄLw CF ^q \:Aa_Í :B :wmIK`Ⱋ 35zV$ / _@R5&c0L4#ͳ wT#z S{AYģ-մ6H9IJ =wҧPC5'J B I-QFqSbe$)@ 5r&F31@@b'R3gɓ'%??i57pU#УE< _<)Y9N>l < |bh ZHBB/bbc$<g(,(4 ·iǐ֞,"7G'v"&o I'$DѰ5i>ZF>.r{Ci<-zmo1!'Nt azwp1_*o51I5cE }xo" 5Ѐ7V+)6Py Q`Fa*$:"$^-?.B fH}OLcot`eLFͨ>(CtjCi`3@֏#7RX>h!z]Mv=ЁUWa.D:qa~Oa^`|?/y@)cr@P^|K5H{ǑxB/"XK:&y gΜLzV<þ8rE]O~)Ojx~$r1#CҰ /mq ~hgJtΔ8G} )H.BLNP/2IuH`ܝB㻄[p\rO*ޒʒ*d:ڥb ͛ n_-#$%8{~X rU5˴R-It?s[[ʄ꘰c'` @OV8.ѦР <t4! fOt˽ ,+{xӢ;Sz+5i29 jo*">^eqWw;eOH..D#5Rze CIuE+SL{1f&T,0嫃d$ GkwxerVbgGW˄LoT|2s]g="t.E#t30I#h&l[9m,H#T= =Q%WK({:tb NtC:.ᗀB,##C^ꁤS[N* j:΢G!X2SkBSfl(zA1=O 8o A,v)Z~Eٺ0C1~ 14 @" IA (_lrZ^tzI\ 9dK ZZ O~y3fE!ں{NTBt=+U"< tڜ!ՃӜ͒h8(vJ2ғkX#&ʷu<-[?zp^o3;%6K\IR]{Iw6p lJ(j8tP3cJeV4O!@<8] 76r vfҐ76`WctqԺe,o xQ !`AIL^UMk+sd>C|x#61/ÛJk1 T OUC;[7"t;!N+:0yKMo$&:)*9(6H]U.s]s"LŕUUK1 I`oEl+7o(<,^6D骯3|XUxJ} j''_pN?uKX(q0,{:I'ޒM`vyd<1pO l*=֪q/U>X!yEj3Ҋ)tzI' . u|oYy0]|YyB͞=[Kޚ0.DիA/sp^M >˕Wԧ`<|X^i/OUfjjW; =4XAd40(>$:)~;_QM6nBDfZW mE"XZM) <,^-nkh-yV!u1Ϯ|/遝6#Bq[ +kT'AӧyߤSbVPi-BV"athP3h3L&mwJqʏy@?6v-Ì_16ٴ`MfO_bv0,aRqՄ4Cenkgŕ2yth&s7d{Jξ#>Rc [eէx7=~fˡ*y.hJ|?l]_1ˮةndU}B^Y_ K/N2tbY |x H's< ] ӂngU! ~Ll0}I;KG{7A:A Q>1b_q4 dǎ2w\m {y̢EyI( 8PJ&R#FPR$JJJkA5,*CĖWxG! &9X'KeCT$|)@ ĺ$3KR\]; *ǀhBNI<fU,$=,h0mpx5D/ڻx8;zVrFL ΎF.褄U]!xu|ǁ?81ilԱ).|lG8#X5j*Y2CH!H }oZ|ʗ3o#Hi8lbH>4TUKKOI!+0{ݘ85 =[-|$ʫeqNɋi &mIǪyBSxÙ.KȦ50^m%p`oˍ$dQK7|tpλ1q,}Z.)Ȣ. d*`OZ댫L? P7otY_?DatYWC m IAtw/..S/ONnRcƀFdQQ (ι,J!-glWx OEjIw/DK-MjtKr$dfXtEX< m@oO e@J2HLcEHٸC u,^VeH8^w0px]OyK B%^X+TJzXks< x2A9L1親9n vtZNc;$:ʒnypq|5DaB}~o>,&NÆjvc=.>m H'YW9V!˥W B=^6d?YH@y8p@ 9r$oNDW$I/ZǏBPLr(<-!i5p"!n44Тf`+6PychCM֭$`7?&t}qQy;i91C14h筥8onPkzC؂ބ)dQ `q8`_t[b'~| ?>W6c&[7u:ZqC$q^}[u6fnh0pB1c=ݫbWwDaٞZ:p%q8. l' Sx=zGZ=djBk5x:^gߙX*ȧEl`-^wT)]LU`J׼,Hw\b+* 񊌘OȥtL8]m5IiA݅'+ȈACdGw jMD9f ʹf3c؟G\[*K.KW7ɞ WuM@3+ utzp:х@ ~"N<"x^Gwx|%'O1e`'@0{8.`Hǧ^D΄I& !!{ FJ+W8eð;0di= F@%?Hv]4@W5/,Xj2Z=$nO,Zy*h}M7jG$1\'ÿ!i=o13|4k+Ox(INqXIjGu/bd!O[vę@Q7ڌP$xAFVx7b V~i%O≁ŷmۦyb-%6Ԟ?$sgQ[2 d>nqbH@nݸҀ&V5с_dsd snZ%ƊlH+|Tyd\@xY9O$gix8"{@ fj~@HRvuorVŶ.*`ID ' FGmۅ4<+u25<[-Xdl<$ژɍy" .=r1cۛHdKiEm0 ֽ~uC G Z_0JHBPG@}H޳PC 񧤼1eͶ2 X6Bo`I(@©L&N2$s8<'0f t SLtד$ӧOW3]t `h.3@A ybyw],d_@d4Z;zӱEP+fMBl4sxLFne@x;7^ gӼ:pJ*L*ztBVG'˪Cb5LTḡ݉޻A42:j6cJ^]xN1\]≗=l"0Tx (:"70NlF8@=UqD-1z A%im&qXcԺ%Ő> z`tëc[ޅh38gWUa`;pg;v\mXOG*Sw,(aIDx9pJ)UQ)FA'j+5OsraW]uS-IrBĻj/ҁ|>q쪐wL/^q OVV"Nn rUq2ydyu9x'֐{X~ Ѓ251˗Mfwp4{ xH786s&^-1!" ޅUj]\DD"\iw3N^Hdz tԚ#N@)mXx 28M#fdC3}+nzP5 Bݰ 5 ySTT]nTΜ1^x"8gsx{bTN 0hirmtWq:* fB݄!vY=|͏aHЀA>܁[d * 7D7 a* ֙UV+镙R" VY0ՉĴOA=/˧wi`pó^UX9$]yR Pʢ3ra$x,c=eH*ݢu~J^P*.!x(a:jNxM\1kHPmhKy֦2Y8[Fлi R+.[`9x{j0dιN韤3G*cx9|Z7C#'K\: d$zi*tEE8eۀ `sωncDzgSΟ?{@ѳCG.,瀧o|>n;rk yWDd%%L 1XՉ)NU cy E]?$zRO[nyqCWw$ɮڠmmo͓9|*ѺY7NI4@r+kw.4q"&hhxP;M .# oJ]?ٴ Ue~YZ_@!`H@ո{N&x%"0 W6ڝe2ad2XIbhʼ)Nh_&:|\y?-;"=zE3Y|5MeH֞_U7yf*; LϮGo$b$@f |d̠2 o`wg8DAq+k1 N|!òY. 2* ơlZL 4X.Iyrr )t8j/$2tnb;lG***94{J0IS v:I;j, D~VK4xX˒wN,n}ɯPH5|KyG\x!Mm;<>Ri_9i,?.ShxH{C|̢]1hgT-x;  lDIj}JXXB=._-eM.-V',(囥8Z5-M4I և,A9"'O;vA$.U0m;lR6t u}I=5LgX4CnM @bh@m(Memz~_5:d1:xrY5ǃ֠hT!]轻LbI66sXpzWǠIr2^s[~(pN$5g<| N u yͮd :DeadzXdb21.yte̅WgSX>Y4bqZyRܷ1L TZx_@T=,`"**P<`⋧ō[|R1U&JjpE.AӍ.oH4r xP.4Hp&z+yNtʨQ0,JrrPh  p?Z}440ϣ:ZIojլVĴ 9=Pa~V*zvɳ%@!0N C7HfY29>j9t5jo7VOIOǕRT|jhƒ,RcƆcD<5:X\\ pDݝϒgkGߖhuӪ}7 bž:K,QzʎΟ?/;wz&/3claM#[ʈ@F#ZUy3¥5OG{Zu "Rf{crٺ7=.dfO/)˦c.Cjp D>tK|O]*U0&gxqGWsM bM݅xXˤd0k1(yߤ\vt~|8 ֣CWZ|u=r , %UJK={̶H'kmMB[O`-X8o/n:tH` ŠΈï X J' lZ~wxQ|[`46|RH6M>z;=ᤅ)qJs%̐V*c.毺.uܣ 8O߽hڋ0;|k+e,wl(5ϼ_ղqb5Y*%; \M|I:.^Xhܓx-[XH=t4S& kO|ir]Q:w []B_O iG2ӞYBRp{V ޯ gykWz,/vW?1FnYPIݥ:j#%iA̚?+.#oׄPQy KSfh}=_fi`J+s=$x=.Y8 ,pPLsȻǛP=*3`zӯ q EW7LEj0tY1c(}ɹs]'|xb5 e*K i9;PnvTұ~m Q`kД}T G'"Iۓrꩫ$/~$ef)I鮒ԼdͣlvK(_M2G+Bǃ^ 'T}4h` ꩪ-xlU .H=ͤl+gϞU1_;#E|)ww4{w災"{ɡ31=p6gv~ZF,A'5U\ a"yj+J]a*~R}ag/M cܛu*kŰ"brǏ5E]0H3uzmWrK!\8V> f@IDAT| x O!>S&t3B-@jkጠ|ė>NED:18'.kmRN)n̞z8x A/+#S"}wJ0̙fT:uPH@}T(5ﰘs:ehSeT)A`q3]NUOof7{EЎ(~v7dIuUKe,QrM6׍%xJڋ$g|3mcr3䋿Rf_3}]>  bq|r&wy|KsZtOgbf|Ѵɓ$z:q8p@Mr 26X e Xi(ߝܗM=jԑOқ+VچvYFN-$usBe/@ فY-mCA%SBVɳ+12k0f_2x aA {DkCZP V:Ik'I7, ',XEp9K5MZ^JUSEp=@i Xip-4 'h,S+l^3 uph2N+#MP1P {tYƀ ςV>P4 L!~(^%"ObT >LqmS}&"@\:(/ ˧Hг Fp7|a H \[;Q٣ʼ]7$T$XHF=$?y>W$\Y.vX#޵t|K,*+&fEDZq%e%(d]xjRyeg<9*'\1z$& ,=n ) КGI\[@ܹstc_MK@A V8\2n5ZFX?V+™.l #Cpikx2Ry< 2gS.ò0)./Ҥ:WAp_WK\ 2I3ۺ %ҁG#>L<0WJXJv_V5qbƅ=  %ܾ<$ Ա`8IxkBP-x~JT=`xYہHrN~at%&W#c3ФEsTML˧P!"cry|czX;-um  (f{YfOދ_7Zf35`)mLSBnȲTT•cr‹:T7ɪJ0eQ #Ɏ=3 i>[JEn1i#EX懪LXT"ej 4`ɧeV`x̧iZ|[?E|")tACW&h (Fjg~H4ި6T%mt+㱱>]%r~ dR>yqZK]l^ެꖄЅe/*r iĠ@)u(1u`xB9lzw^&W;"UM\Fs4{_nʟ"+n*@0k8fwrσs;/`aH/@^iK0`9vɓzeڴiIJL?Τ'1ٵk462ldc#VDBFx11p:1ʺuGVj[+ڜq'8ƽ3܍^ ;[^OVxnO$`Fyb]?Z :z҈|ꮈhݕ*Ŏu|}o<\?$Oass?~\̜93_G H}ns(ahԓNGoJ?NSF|,z44-I5tF͙e,PS.p\5cAur*- &tqWxm kf;}%xwvp%:)p쀑 ،e;̒ǣRQِӶ}ogIU>i7s41r"w3#x۷8O?nc[j XU82Pnw,kW8OMɒ>9E yOKIUƿ18p r X ^tgcr|l˄ ri),CmmZ-ҏ+[lWWp BRR4,k l iɸEɦROnd%519_o /f+y}?PB).tO`KjYc.F}6x**ß\,6Mbe(j&0 t53dۖeۦS*6ݤX $5!nGX}D KS{\|cJEBhڸqc t VPN~0b/ X ,.go@^_8ʡp."1^Re|EkWH;8%z$_bFFfS m*<k''>T~TzF;rW+Ք䲍S1O-~Z)1R54Wqoؐy9zಜ? fmEl} ~)R_}b~쉵JkGT7ۤ dTCc֭1:|"4Qh )b5OS>ݭ-+G@>Q%\Ѳ(Y Σ+Hߌ͋dWJa/ e,0Γd뾈ܾdhX?q6uT./m lًM 9]0,.ų=PtERF\7) N &ēq-قsyHG$n\ĘN LXZ=A(%o[C\`ԙt;[IV`Ve;R>N~ܳg0f̘P+{M%(gU+Dp#%`>)*Fvx*RE찹q'-wpHKSۙi){kIJP7$5LXuS;iU') SVP]⩼< ̵-4mV8fUN_//AP趜C]?|X<88n8Fɨj f˹̆WAŝo@@^\Xw;(J~k հςj k!?f!x6{v'xM~J̛> +cʈOˢ\? EXiq";dzʑ 8CM|(T nNK|ƖS H^b)/G+6uQR 6`@W%SnXn ˢy'҉aʚvٰAT-פ]E_t^X {`& ٽ{,\P0ղ"p,'2ecbRWGZ c1>oVQ~NL}] KiR|`n@/kѝIm{q3g|ٛLS 4gJ>$L Y8aɪʫ+iGʺit3.$R $QZjfv}Hj8);o9}*$ B t/'Ģ1ڷ&uJ:c4Ҵ.-l[+ X)n׀C"u1[Z7fV1_e~'`-vS+o eI3n6<͊@o4n|y'xmiCw'X ,m@ ^Rysş='f4c?= @A<맥p3"07EdZס~ ćxO͆н#1p{@4||`'"@*v\ ;{V$P=(An 1nTϺv#|4qTVԷ {Z"j%+#E_o. e (l?;w?^M)r^}_Þ|0`[p&uRA<.pQ$VTgiKr$s[q4yS}uxdIʈxB yɎk&+]κ1?.X2gCH(}u,\2V-'NJS~o\ o"RٰSE7 Gy`%?5`ɧoQj> $ԠəO}@l~Z/.|*S>|[F0nnf|U:fS8vYBIS z]rQH]= /yDaz7_l,}j$H+BM{o(0N$1?|xE:a)^']OKL=yNWr`ֺVY^mŪD0x*=NP!| K&E2H (C:1ӑ#GԩSAhv\70y58d7&\B 9? HYz)/G ﻡ:S / 09%NXiCk2Sw1501,w7W/$pY{n qy|㔜9M}Y7!^[<.4CJ$->qU";i#_T+b04TkzGDv -y(^Z 9S8өmU ^,+q2m_XD|SmF9^G0_{B%?.~R[N™A\?+B="c0ټAC' &:o!u·+VCU|>wd̙3t?2I8qBOte.o.֭ - 8w ˰FLnW!9B)B4J")_03Ks$uM9_Pҥ/jbR~պcTq]2 fKiHyV[90~:_?^:z ғxj5r11PMD W8^xV+VyRC %x't={ '_?,_43sG>HE" @Y˕FDey 9y)bWȚ#.u:x% )_I(wrkqDlS~)B+ΩkC0]e;#>IwZkn0,pY+V}v,$ui17oJ%Nup x p|Ӏ!7 ܄cZ@)j̘1Jc;Ңf{ɫNKlaNTxp =0\\ශqtR#uu;ܮRNBv}ԉ<yvv0+] B l2y* J?i* ek%<-vH<2}2rđJijBVrR $_OXk ؞/o_ ^_Qvϣ]vɈ/[|"e[5 #7C;䩍5|Oԇ1eQ^$=W)*H.*xtSy_BN&o#߰^\1 YDτ\!Ef )s+Br&UtHŮCm^ŗ:a.4Q C(@;ΰb50t5@2u-% I@]p!A *SHPDžN]N̓# H|Y1vo rp6Ewajc9fJk۩ev CE}qI2qrqW+ WXxXqilnOyWUBND=il?Wm8/J8SYOV^|[ pT{"c\d2]@A7?#ʤnXJ^Y ɛk#u3{nSȓ(ȓSM/iqD=E7F8D}3]]cģrQtc quY |ہ/ŗi_3#(kVkR!ۃhDx_*VJC=kcPgY( (8X BY!wBkfg|ڧKl7[ׁK77  @0q̰aӀHYpl 1`<ۘ=./\G:;35Ume5c O kȘ !|cAMEZ_|Z\R򞜎>'J' B46Ҁ%pT qd؋=ϓ7u,?_3JaSElj!ՌB>nc>|ksEHY>w;$ZvU9//?P,kVJE҉1vhRՎw.=8{ 83@Lp -3d8Qgv$+BtVM~\6f"\ZO-J'8d$VtOXb50\4en ^a<7sLTgZw1eH~=!̃S+Sqr>`@" 0[ܶ%t" l;q9TN_M}&xGtUixM^vuWRF5ށ ㅈ8Xphj@i潵RnKoa[ X + XiX~W}"jX=5/%3C-p'T.Ob%s`\' ]r"xNskL^E_ %M˥T+kll<#|DIhm<`t91GH'Wj> | K I1{ݭY>^WP϶/`}aG7=1Τ| 4`ehL$i`&ছ:u!lx'I'KB CPH*%|`4ZF@%w}/pNgN$G'C #t>)Im)Ovr_GQ9<#G¾RZ)F. S pC3\F nVKOQyIn8"mW/߷?O3oƶր%e% K?hEnn+X5_FL[6#P3f+˦ _Q%^XIޫgdru"D1 "ɳ@b{թQLuc]ki*do|fN)nMu9G^ (^!/7TəZoGNÊ@-H?>HXb(&=eĭX"/܅>JN7Yipb|nhaxӬH(}D5ժNm7Ismrɐ1e?,-]I=1{f\-R0f|{BVXO a2T{Q-\iSNil=#5'3'V] {+VyK>-Z桄 ;ѣܔ}tz}OܺD}TrKݲbavl0<ǤO4UO1fctϜbXkIBM[.a TA׻8K$xHw7˳jdVLG M^rIrV8 < 0Rf#3VrLLflO'Ob3(:Xza]?R 0T ' ovr];<#HR#|4,VB)&LBbPH; A}rn%,%%hTiF2iZqˤ@@ ֶZwD cAj?z4VR|X &Pq(8\2^b@R\U7qWL7E̞3u_-:9sY8-EH#^@H>-s)k&,}/j[)MT׼_hF˯ u`%@҉_2Nw, +iXr1TCi=i= :tlZYV*j8m'@%K=rVBQoہ9h$ɥY$X9ؖ҇LO&\ån 0b`b6;TIn'_]>C0tIn^\=YrI e^b=Sʎ9kP׸u^V/Cgaʴ"8DNV CuJ4p5Zj b0 yԷu;,wp> Ӏ% HiC J2SOk-{!|tȘf W/ !>S"tf3M鸟>*?E\MoHsK:d2q@g/rx?OIYG>"k`Hx9%Ϡ*eZYF ; |` ܀X t*cEXɞHZ$)LeXN$h1v`ZDž-*.W@R )&~prХlf\Uc^g&=*H](pb}rr)UZ;߰_]`=p kOP"}fCW_& E$WN `|q: ˧y!EO'd曹WFs:2Яz~uD⳪<_JaNjNtxq906U.(h `pж(*@**7yr+ל8BY[P(FzFr5(خX ,i@ ƋV0/XaԩAU&~&L{ke<^3H)U@>Źv)䫏ۖ_PI,PhmTv[׆$Y2Kuyව ;+%Z0,]]JJ=ԕϳᮀT4w5huNNԘ$SN+R?p6ω:h_IrMmցkz3]nw]6^In}3׀% v |RaƽcղO]@}/|j[kUE2mr>'"ꐛ:/'nS(O~-(5䫵+UR]*+{?x`|3)Ǖ>6%^@vt7=2E+*3E 9,X-[c֎6SL='+%X X X lI`YЮ1(nnwPT0@x3L%k_.4l9I<-{`[K#z/5I<'s{(aY+_jYuԳSǺp4*d'mZ(t(߫q_\H21w{ FKQ,DBVD<ߴrE/6#3KRGrP.xPя8~)`ipc!&XpUIc[%\6QwCO~ߊ@^jOyy۲^ha4  SY0_ihdHKWQƣ`'c<'[|rI_205 ELy>{Yvk' ;>l!9`>+@S@:E%~) !@:&= a>n0X+טEus̅ǀ!$l[ȵK-hӋ3_}r%b 'C_t؂Ml=ڑs22MzYOeFuꬻ6as:_!RO5e: r7f\$uD}2vӭhԀ15B5`ַV bL3:,>9$ih忼Y+ߤTS+@%L!wfЧ鯀׀\[_,iOYRdg&X(SeǵL/:kwx s\LS#O?{Z`䈑tۅ^(O;-[v]cC;_ډ.}t˕#փ@tF9L1"w,q?7cת qv˓/Wˉs:KZl< | X Jb5`50d4p%p p;KEBQ/hN Ӑr㡬g&a/#~ٰU̞P. aEIeEm_+; ^lbk9UQ*@IDAT.\-f( VH KvtY&A,kI>ءc,tߑ$L̶&V&M'= ƒ5z 9v940O";E~C{\=/UM$pHZZՓkZK\"H6Nǝ<,8DCbMwr#1E* B>.|6u ?4UQ^ۜU+VK>=58}[Ÿ\9U8^'O앥sR]gx@jV/60ؑ `*KZ:=p %A؅e;qDNil _/Vj? ; _~ \AZ e-0_Z\GaZ'c"HZXMl/\;!H6%'Ϝ0rƔ/e41|xIn.TqrZ:bmfH^jej, %~&یT 8mӊM3-05?^]xD I@7:flH\@]]e&A2R q$|2%uY?eVyċkޕxhk4C,G;|h_LۯcජHa$ P %^Sn\L|4Z:Sjf~YŠM5 wČH21Vb!A)\Bd ]C%9S^- ހxP𸀛vm&E1qkQEKwe^TtFS]/π~6t}XGny KJcej Q゘Ɖ%\6ZGrT7ʆ}҄CIWX: e: /33DcאRʲ}6P?#O'j"~m} %40H,u!8גay,N3"Q׉ӂ>"X#V|JKz D 0B VRlт:8ҹ͘ڻJ#75/U$&J8[&u43t(D]lelݹq4%:Oja-RKcγzY<ū*c kd6KU_z vV.տ!Uu*W[*8_'D7LrBXb5`505`ɧxW^'lUgH"ˢr̎<i2r̷ǁK{X˖ |tK-ԍa@ӃX:ZP!UqsJߧ.o6ʋ[rAqɄTauAkb%Xk P"܄TmRt7b2̆XcsPq7N ]4ᢷu]ƒ19.z+y%Y8OgOsjijJTez5:(GOW+O 'LճJǓT8Q%.t3Z Jb5`55*35ރ@ e7ju7a{:E@'iڄYdT }5[عǁěZc rTރ{a+Iq7r/$ϊՀՀ@>hLL KFD2c \WRPP ^.Ԥ;6 5S JH$I;'ZdnLˡ˧h~*[ҘhE|-vI'vKIR_D#*pI@ȰJ]B%軌8N_5ӕjSᯁb|9]yKbRƏ*w*>gN]DaK> ^}-XNaӈTN#j}Գ6%FN"tʰit)>b_,tb9,O"k9~O < D;X X i lzti3,8֡ Iфu e2f)++nˡCĉRWpGn@:ioA˚am:ChBKIOaZd' 2ReJ^'3mNϕDu6շ[`mWbAqTBR]Sj({ABFԅե2mU0%MUBhwAm<#-N~~8}ŠՀՀ5`ɧ+f`7T,#Zx?d>:w0VJFwlīy['uw-dL)MO}$X¸NNdz|aɻkH@6uҘ"8 H%9_}-OfKK,}1>9b58%RPc3 $P0EFmTܡ|86WfC_QVVjOݪgSG̜1-F”. -)\In5| 0 H-kn, D79^%ԂFKUrD}WqxߟUo>[ȢwsZ6i wz!D˦'ɓպSVMҦOOXJM:U/U| Sl)l@l')snszyJoʖz>s:pi,HTy1ک.*SWݖ^'A;;֋RxD92l4@+Pȍ"ɯ],@t"wOU[ZЀ%CCfԦC awܓ<ėޱrƶ,5.vtS/L.tg,<`h;q*5+VVVILqH81 p¶ӛ%Z6M0A.up2K[*lq;I56]+'Dd9e9/u&^2%zNӯ=pikkJd,'J׌gLs$LIѵk1Khm+#]N]~J`"TޝF۪<x+jOWT͈:Ba̧V̄Avr {]"^w/R|("[($r@*f-Npy:ź*9{YJfƷCg%@w;;PX X \| P2dS751NSqqr[!Z=]-2 c>EQU]N3%d3nM{IN\&)!ǵgPBWi)Ue]c&zRWF/$}QXjZ50O,xf+V@(<{ \}`7fSv ϊՀՀ50I+*e`z|joAR7,o|>#M[o7tS`@>",˴nBMz#.HlW_|ԤJC?E6bijjj  #`Z3]"t8a4a0p 'YH61P8 (d BR:uJY>q?Oޙ8%j[6siLjda56NurxNqUz-Y̲ujM6i ۓ6Fٵq!Zw$䟦>u7{eC6aK> jPq:2|c&<.!>U GdI;(w.YWJ5` Swk| uNg+͵ܦ(fkQT)n hmb5`5`50`[HFf@:b0HjJ{  %(&. 3+]&لu\H9s"W:> ,Q+[t\L3(f;rf}.u\6sɷwiXz.դI&s"jik]Yi!+VԀ?P0fު#'W/D5)jV:iOT2"wpea.Ԍ@WT{r` zD@GH>K\t>AN[ ՈԨpM# PظNP}dc:$H2/ƚz\:g#DuTW:ng۝yv%\ɓR]w%S}&W?mqv"~+|^u{SiF5iLnκ^-Z;<'s;SRHd 2^Ф>uw+V8w~>Oq~iFY?fH7M*=ncxJb5`5Y|ꬓݲnQOMvKՋ5TzftN:) Qs0y.pRiFsc45+”Ϸ%ںUEL\1Kᐴױ&SK+VVVi@Ze5e,b|Dw0p}Xɱ> 鿕JboU\p÷"핁S{/T%-kfyzclۘ(=?n5Vyb`<;Z9M4Ph4zh5jnbpMz2/A:PNRYY)555n>h)NG"mܐ%~1IPᗆ5#YW֕TFkMɼtҒc$$؊8HZ='5ˌO/+MG;8wv"3 VX X X  WR.{v+jջ]wTIJ=n|%\|$yҐƚk&t'~LH|P zDW:ߟWdSV&Q'P^wq Gy ڀ:$]Rq8}$wix%S>]m'bʖ4=]WO~v6 s` Tʁb1yN,;'5V~\ٚ\ǁx fn4kv``'(Հ@)^3 pDY5|jU :ՌO:bUe:9Tkɗb÷=p+ ԗV8{+̣qHTq-{dzyx=cη7;ga4&L-'M p@xWB+&gܦ &(:NJ mC,wU}ϟg'd{ȧr5_+;8 3WHfir\IlIkZo>jmCiM%j4•ҵbm$kob5 w>XM*<`Y#GS#VSB#~hEfKœɀ ߟ3Lt9`5a[b;b7ʄuhN]//7##tR#.kI'U+VVV [T qΑ%Sqq4n8,< %b7,v@J^zWLLtsvGFIu*C$߱M?0H5НVRKSu׷4:!w lK,MH/6Ce6|@]քS {gIUީe/NZHh IDEUi#t՟)0R&AWU!_فŎ]NU Y,$]b{D!n?0vV+4I393d 6p;7^{ցq 0q4F9ZRwSʚ^zUW{o.yv{/`ZЛ@HNwәxaߒh଻ L U`6lRr: 6SUUМhbG'iV& g;ϙΰ\f}'dʗ+.âѨD"'nqHB4u!8̓Y+BF;SH\I_ai" 3dz]S.nsgbiHr;qINCg{WjA o*ur<׶yY \ $0ւO'ث[ L; XiݒV'i2rY1! )L-'џ'l5@)??_HW]]-d)lF$g숹9Ü@ILI vR <w)3Lzzz3Džs.3^לsa2)̫Et| $eJ Ü4,m|V qDM\MRXX8徛 d$^ۄqd:fؓ p'J"CSIS[E 0#)PR0/ce_Oܧ!U7u4_'N x#t4}יHhtZL4RM. Y#MUHKT1ccpj"1KY cziz%+++% >H@5G­Ȋ@, z?hbbi2x}0G/Ja`a͔pS9sh9efb~47(Ǝ,94Lw"Y6[Ȑz($L<]m鏴+ m57ՖJ8IOI30[j7 kN~05p4'NnSiYZ8 rΆ@$C1$ ::ְ2۾/ex |+Ot,Y X +oZ >|ëˉ$i4 ;f11"C`0Ùeh'X2LPiU\gZgy< "r>5B`Np ֒9斠n"N0IcӘKcL]NڙZ꼏ߵFNJjOڔDW|.L%mV3LМGC͊gXG(nV[#;  q%+++mVd`% 8@m 0a`U$ZPxj?M·_7?JvԈ1/+o.&nvR!l1F :E̶>ݣ.NRh4#!^`NFl-Y X X 8%@sSW_&T&vȬPG 'pZ`p uG7K$ZLՕ2#L6a'DfH&`D JR[=siqq['pTbE5O2o^X~^.Rh@wNa/:ԯwӡ&3f84Lo cL+x,Kع1\nIb"ixԫ3_}OᇬE-[ÊʄxV zQ W+Ą?WO?cJJdI d^w:H#Mg2#d@?zn䈒_2= X/B6÷oX,ҠS\?<)I?Ds0'2,Y X X 8%y 03e &j,qrYhQj::gRAVJTR&q[?AbfR% m!TbdӚrk͹ y Gs/&ȵ 2O#8L+yL]`xەt8(0!Hk; iH#b 2{3&8t]LJɔהeJuZ'0W #]N}fͥ"_0S% 7S3fs2}:L"rp'Xw,رd%`%0w%`{kNA}љf1z%/5S >l~%ശz%h;-Eٍ b.JN yvۀd3$}2XJ'fR]KVVVJ-rljOp\̛7Om▾XD Iǵ$dvx3Wo ,h*Drj)1xjLgZJ(1o2le&/ɴfO2\F3| >,~$$&0`1P ׺4x3'xdḏNGda`EW q2%VQXb [i<2qzw@-ZCt6ܩKqp,qllv0zKVVs\|Q쫑q$0(ǩQ~K9@jOR|;5tzY7 UWMהSp"ofH( :94:tbrNL QAu`+NMM N5kָ6T__hGЉK\2!6FbdDL_IGaR"Dm&N(>ɼsIEx둍$U zR g6`u 2TH35 kljSޣai@"hbJ"㇯'ZTqi6 nKS/0cYT8.{|[ lYtmU&* >MTr/GE<$Q8ˤ4Y S=+,<0:vzsr%;y9Z tvҼK3DM߂ ~ Hd%`%0G$vh | lVc?EɵuV%C4nfqQQL`A!p' ج3faZx_O@%'WthzF  01"Mf>cTIf:Mյ̓ȮxNiBq"|թn浙-H.OE?|57b(ۃG 4>{FԴLWwT'5.cQxce:XLE'r &EE~ZNח~HN) w ȽOvs;z$LMx |g` :ATDgᗃ/S; L-'N9 M.j8 =léDM%j\-6d"?T}Plɘr0v-QՈw:څN0?U$x{ EK'̐Jo35iԉ5e~3L(4Ј7/K>Rtt%D}a|wqu&KO~_{e19_q"PjC]q٫2n͕h<tDݳ9H`r{ S6 0?I?%++9, aȪ! FxȯǃhGN#!ӂN`^7đ8Ssb+t,Y X F9q%Dqɴ\ Ѣ1 vm)e4 "_Tv7dh)~/+^<^O0] xyl2>xq^יHփ鰘ɱǡyX\"!}PJCxl2}t^½Qik VCHy&5OsC]ٟDOnW!\Z-^v] < ?{akf%`%0D"9`!CHE M|b6󫳙`!keE@<ڧ4:Rx0qw@G屭=ҋecDKO !v-Y X X A=`0;`aSex 1&l`>4}l>q }C I"}n8/W? >kab ѯ/ZMi0*6s5q 0dgZupK_1 J1dqw;FF[- }Fk*倒=ǻKrL鲹`ׇ:O|⽚{5 > u,ŸSBշuylfm=>8JQ(3ub;I`z:, :ă3N? m1^#>%QN~&DN9´d%`%`%0vl0R+lhp>ӈ f:]1~N:Vx0r1 R02-'x]gDLj<s!fe`3(*w,Oi 23ELC(&92:sj`s L4색twIO=Ta4x1R!Ք]os\&˅{I5TtMtYeŒOሔU4$O4 FNTn%d{KU&;+9+) >~k!g(lWb-ˌr4j@'totd O 딆cO1ExL` Nf:;,1e?@WFǘ;| `NX?(̺$//O@\|~bdž9nӤqLLL.W|0 WE QquYIGvME(-O= 04'%0jh髌'lg5q!4BN64w&"0|wVJ`d Xid̥fZr@c"Ģps3`NfKͅRptЉ_0vs^WKRJJˤrWJ~a1{OA5 ~O?&ghDpR?7 x&j*ݿ44zp[AѡN!HtaA1iLuLԧqK$)}۱RQUw }5+,kFLiND-q)s j@,2}gtPJyơM+]\Im,@"N#A Yɬ=>4]S|-;%`jIh6ٞY}D9 z3`siA+Q(oD1GQ4N}rF:u#/t)gYi2 05WF#v A?'j3T!ӒO2N̼[](ZPPƕ/\v|n,:/o!ri8|vNMsՑ?~?rS3)j:-]T6l ,;wBW4 =3r^HQ2;Ѧ$ 1eIi(.:#={G9E tZCkd~5i=Cltvݣ]:׉Wht$bkJJJdK A|K%`1g"h/eKlCl cwTr]1`,^`"/DQ@_/{U緸+*\7 jU~oX=\7wd7:m_w_kWMޏOʺg+]w){vmRYX#|.PARģWG1se:_&H@&UUUr)Ȳe$ J(B:W$OIt_}cɤpe[c54&\gjxPp!iyY#Aeec-#Sҿ:?ixXAQ.FMi0Mt(+7G\@<Cͧ"T7B-a睔%+9,:{Owi~K:c K<0Fs=Ng :`PnD [NF"N?4;urر #d%`%`%0 dK#pè*c `<56\Θ1?1N)32^`~bߞ=w6׻n,_; ?ůy_=`syZzǻ?ye۫[%W ŅEE ]ťRuIQQSZͥ?s"E̍k_/+/.ͧIi!;1L$F)5X]^>tYRm%+++H@ Ͳd"DgH&7&To1H;/RKĺ:ko  <>-[+"?C4]nK \K@[0O %e.Po@FNH= K>}@ t `"GȂ oNHp~%L l!\ ʕ@IDAT$>|" .@/^,@@I !.FATn *;|`,o.X9 J$}_g.؄4,1Kwɱ'$W{ [VXӕnhCh$qr\t#ˁ1Mɤ15o(* kJ˯T|oۚCpޕ@ͽxsG Gj? ~s|oJJ`K|sgU]Ը)x >/8&%`WfvlZQ n.7ȣ#OCԡ q.Nindqr0u֒%m<"3ւ  Rm˜dh 1MPs)/Ps>W /(g{̯#uk/?) 7p=;7Y-_$/ tNˤ @],,>O WYKEDʃ3+FmrhkUe,v|E: UCq dS747pnOhHiBފ!Ƀ$.WF"0k%Kp'xD;qm@sX9],:9G@6,+& ȼ8o Cu^OL(5g'vΐ\iUtLdSMk: McO֭Cy\=IST;#籮+SN4zUq.1Y*6GaMs+܃9XEvDb,4p58;8PGE=ܣ*{Z'7O=tN~zN˙kRN:2^LݯG`b9&49 >ckJJ`Km9eIfD9Io@&]<d"6T (N'@岠jASi_o{I**˙lPYh\vptȃ-lR+uޭ*%eOo'^rkPwH p J>@+t֓Mwt(0 8@&^;vJhz>XFy5[K9?O*/PZSuu{eŪ6l:C9O,$-Ȥ82:UPkĥٛWG @3"jV-_\>l!E |XZZZL豒fSJw$JRCIQ`9|dy0L&FzKxdb 4xOOxj"Ty| Z}޼p6{`CgޚLKʪs)7CFͿcM=r`D/X `m,Nì8|Zgsmu#$x"?|JvJJ`2dz+g?6_ư;}ȂO^pFFi J?O+o?@6`^wj& bq8|0~P4 YŮ i&[]`B$\&j-`F99 g~dD AjLZr4NJVw_V(l}At߯kI=o]R@_YQ5{+rMgG?iٷwtIil:'K/#h0a*gڤCVʻCC@<h a( 0;t`/i dPk),e+V*0'ۛN=[wdZTZiJ+C 9|_i>QS ZW6]przLUg\}[ݩnpL^"opR -˯|\|u{@Dm,/=0)3>}+ӝA jmѩڕrnj<|xrCq2Py^>$*j8)TXJԏW2z\iTuFM% I@,ԷW)Y1TL9+{ |r?DiD:)y쟸4F2Y{[4♧_4KQo8SQUΨP'ռ'ưd%`%0 \Dv5=;؝dqC)8Иhgj;Hv4gsK΀y[/+y8:jΒB˫rn?Cy["eKu`;!gIJd%`%0%։L U`j.ll.Dm9 \Ԣ!8P|XOvlY6_t\w aʥW]G˯:Bf,D+UX; VN(.)yr(+"N,j0oN'H-zܓpf{ i(wPY}}}tA8<"-Zפ&N4E+(,ϻX\E-Z,_8]0/$G*/P,^N"@M2 z? TnȃPojZ>=EdakUD'U5(<&0:@S@e`Y ӧRQa# >;|.h"9QEx8|k֬jL2L%᰼6hu(?PgIeCYlD|5s4sX8H?Pu?) mo"D @N XXf^KYW 1P+|wq6>|,!o#,ě7K Mc$\`r֧Lz7WqG$3?d%`%0y "O VؒQ10ӊ,4nI/qp9tXco&fvpW\U.W AtlFe[:垧B;NӯGM]`~uMŁ%++#ZJK6OhȖY>c"T/8DS456yqy_K>?N.y'kYYTyWɖ@.hB`|O Z9nE4즣GFeŋikiBh)ÄFW>h7!9B઱^޶d 酣^yA. Z}B`}8yER -`9s˺ Y0ZJ7K-JsN?]৤[i'9x@Xb^ZS䐤|L֯?Eiuw&R0lkoJvB z΍@R .(D?[WW?PPd ү$pPݴiʼ^r<9ds|N6:gۇً. $}[%؅vIY(I8djW03kL4it(iy O). M`s>%5JOHD.R$Ԍ񘥎#0S۴Nv ]~-Ih|:ExY/KMhv\'vIg)b;ls=>'Zv`j;9~_8oqf5 o9O6,a"WQ;c=Ah\'|Svv(ޅlD=x%+,~9|6; <0pO0v9&q0S#SpvDaqYug_ {vmGG>򉿕&k)N9>6crxTiP;ڐ`5p6P5L#8҆v^OqYy^v)Fϛ'ЌiZ{1Y`Ott y\ |{UQD.wHv9r 8: 0j9O Yl|G^4lt: q ę a,:v#qpͺʁrCS=r (G#UT·C{Î ݲE4t\xy晐Bu :9 okK_Q=Rp6^껣N UhBMsWB'* X4w?-{ wz]w(E.0s OWq|BUɮ9,qzτ2D99iL.nt]d,i3Uxx]]x:x3>S3rcA du)sω Ԧ&uIg;C,~,!XJoZv8\@>yz_b\r8G~y("ntr=֚Af8=05ءqnq@P!WҢE@0Z`! U(K?7匳.C?{_K_\} }ʖ'TZF%p NS1Es80R&h30-Lsn^}V47!/AH4֍FGze_dW2dHWZlsun7_YVUft5K䱈^9sdђe)\;aE0̋&&դBLG@;b&C>?D֬$O?'ܣÓ>ɛy2yTҀAn|ml;u0R֭[|;QiLo&+xjkuR) BLP;'-ާ]c$`t\얶sNW~: U6\Rj_>̏2F߁mo= s9 ,ΓϽoZFCqݖiiCT:mckJJ`fI);Vj9)o"/̵ oKdu0;CV^CKc>`5loh}Z9.JB0?%jh@~ СFnc4CM$47i k_1Gu8U+=85"Cb>G/K^,HDZ>gd|lৎr}v!r[LaUhw ˖-o'ς a58x SQR^xH=e0Tt)1c0ǒjgDT:;#0/SO`?Cr /xL+ %^J&Xt`z/_J0CLt&䄦! :xW_!Y)y+g |^r[9>yCg"|2XKVS+/Ą _9,*Jm &~cG{r=Žl;ڳ ƀWPZܬf7E0[# nEjJ$XT'1a;.1 '9ShOezQ)4 abv^I `}@XǪk]]ZKZ%Ȱz&?~SJ`҆,X7pll׬x |(XэV۱c}ݱ,' z`]IOUlPĕᏈ`Q R"5gLdFkQo| ~e)XQyd{Y g|xPs~MWG]+ٝr)qd炟&Oٵ)x~KKD''(eHq`5$!=W7+}xHYt.+N1ZKkR^QwA{?b?W?LhN69x=F!޵IuNﲑCCac1=PC1w49C, DK-@LvnkPqׁ>.*jP5'ۛL64MNoSi#؀M(9K>^0w.S ͈t O|7Pv+@%w*4kj]lJ+?_ +AiVYq+x8l<'MoUk2 GbKbBӳ%+^L%+Wn[aPO-bÝ8̃~|8`R~ABjo@EE)MzLnFUە9P0QՖi&WMҊyފ|{ZKt4Q buh$DsҲct=u#wɃ;!׬Y#gq]'dLdd] >)όkFNDrR Z4I]$S}r]m@Jֆwq?^d%`%p$ p =RS/{o+3o bc 4 4ϹXN=\- W,2|:1*M$dFS0k8|HiGU΃Q/|9- HkHG<ǺDKzhcbňigIj;i8\'?ɷ7iA'O A'uؑ#GdИ1F Q>kzqa1>/jM'*t-0SϢ_qt>kМdj1SZJ&"ImNNn>-aٵkdނB9]FS~3z /?A~'% nVtp/,dSsd \&ėIpWv s1ys}tL9'$&D@}0*Wf`ҤU`4uj8АK)2R5Аǟ=!i9lXxFO(K]:(zS2Wq44s8 ϐ8'0l|V93I ; p/sd%`%0{%-πyzeɞZ+#pܽGqRD9 A1M{*#FT Gաu.Y"zc&Zylyj̍}Px6%'$j˝&/<\݋ .\.cN: - ?1hd?J<̙&O g78 <<:(ٍx_}X; >""{zJ\8SF#sN(V|RSԭŞRc}2>▜F:+D¨2%7L`\&1* f(| pn˩Y]En)śCC+!/Kv/pxƑf-;nf:HXu˝c%]bs̮'.|K~H~K+$6 U :kRN⛎;7pH6Fz`nkLbp ^ZZcZ,-SbJAR>)ÊytN>]dr>i"m,wq<}4Eoذű`1MNNU륡n~ M0I ~nfaf g%~ w\5'}YF.~h2yVħ54ţE2jGJ)9ɑ#/srPƇc;}xZ DRZiHfœQk/5JKSH̽Uw/Rh|rkvjp_n|5,0`KJ{$CdG--վ@ ڕ oyQqΏU;#:] ߴy Adؐ%Z^J;D@l`jJ9ߩ7Ԝ"`EpfW p&0%`OA0`cD+rv,`ucࣰc}T]+|<)~Aq0I%+J > I)B'ıV.ߜ XՒy~Nyi'VoHTrMHjJJ`Ks - ~Fw~8p޹eW(nyǻ?,z8/6ƪI.0eV&yEЀ$LDBJҙr|81ˣQ{ۿ=;$*m'8WfvK,Q x}'dvj7)&ߏeeGX EIIp&2ԋS: L<}9q)4CzERU=\X/)N k/ Z^yR p aP8WFXpe jsŧZ0)2cs0CmpjDq,D@&|{\-LcJ Ll&BpgSw\ypT= S Ϟ>ˡS@B:SSCwI< e~0K9_[ !_j$6d|( 3Kj;v ݏw뒎 }y`z !XjXmG9}Jَ ~s7 }ße+Оe#OW貫d \vVS\4:NMv&YOOO}6àPpξiӦ\EXm:1 $ѴMi8tpʼ#$&dtj!("g4_|N|(8IOrJ3JDZ]{ rk ^nmezgNjq|H/+b$^Lk9Z<; eʎG*lbis:|# M=;-4=wx+dV71ӵ'\q8_IEz }! !oM:l ΰ A< %Sv"E]/[)\uS-Zg;'Eҭ P7.k|d*yʧe~~?4\@\𱬵G{R>fSa,tҠ/D*0gK).0?:> > fXx5T!|^ׂiBwZr/I(dXח>9%56qQYءS+Ǐ }R~;yck 2fF # >ͰvF?ܛN%Wk=O|CvԅhAT1gJJJ %6ohok OWQ[ MG9Ybn VϯUhdGtxo]w@o% ,Hy+V191U_ғ 8l?'iʘ9u%,Eڥ9,& [qo2M뻇_]A M@yœL&fӔ dWM34HG+,hv͉txb8XS/$0kXf)ؑ[j7;Nq*c';NQQF`uy}rMT#<EHls 0bŢܖikUciiTZjt:>S4;[ vOl/ ~;L%n`Hi,¢ ykv I8Kg|7%9&],"1N2UxyU `uC- ˊ:.V= ]pΓa؅Nޏ~nc>Y (1)j@ (dNl9 5R&TZ>Lg-21ӗ)] i3*S[M1@?I=$sN~ &> Gp/F)Wǣ֒,kJ{_X?xHn]򦷽O,]"ٓw ?tslqnQU8N_<:zj9J%i*'3Q4+фY:$U#N cA0f'+IT%3$P$5<^LK>TyȿU 3<:LLJ`li]ӷWZCaU;~4'?–!GHA=\FKkNr+q(-ԟ+gePyi00ז1ϥ%x<Ҥ&9 `z9rUU.*0m)ms xM\޲-Ƈ\m`{@3%A9sΐJ)(h#Ĝf48FxtTsǴF Scn/ҭFYUքOZo+hwsţ 9 p~%az0*!P!8ՎPK U\Z0gYV7{~Sz%i/Fs,Ӿ^<1酳s`%$C7Y v~Qڌ'ֵL ׂ̺yϡo=fAĒ<,%,%U0!>s7>:5hG9@')/%4I|ʔ\>˦^ `?M} B(m0_8KVVV' `%~x۱0{>Oȹ%^tN+$۷*?7`J[h@Dg{ԨbOE_E-'j3QfuS};?/ƄwbW~/20gPT&԰bKLdrNSNf̐) sˌ# l"Vi:b0tVSK2lMˠҌ;GR{lun)m{Lrp&JÉ d>NzWU],~X1x:yOЖdS4!w%&wyH-`Di JEYRӺM&L6$WB ǣ4̅qY(04@+ PvT MLvU'uPa+ $?M5)Ip'T'4`آ hՑAiTSQVK7ΪYPg-}'qpj+e`N yJufd#чÌnQGa%.YZ ESMbs?5l|H<,!uAQ7Z uSd{6# ;R8홌\2!v'3c!8$6mv?0M`Kgg<)Rl94Z2-(5r|@IEd %ϙ\T#Ɋp5Ŗf^ ٖB?r^@MJIwO龻姷~pvE$(3;w)P&L\B!9r2SWW 2d93'` F|.f0=UelY[2,0'^QJM(h#$ID _nj=8d.yPbΛc2a&ɍ Ԁt7D݊tR)3>Lla*crU2:aԤUI_$5!:Ĝ7LnŽO/Y˦j*hKpwx0|>=dSޤ ;U&hHeyRwڻEV&&)'J &L<0:)>urCu".1BB$#%ޱ4t0r#}CR }ພAiѫL0jkWy%vFx:|CI> 9#yC<4L U(M*`lWRiO?f`;#*cb_؀ Sfֆw˜7[Lχ3[)2, @O .QdM8N5"8d"TEE`LU1|1zcOؔDI3]aԅC-'L{!'~i 4NH`^O4wbN͉niK@}(T7e dJJJxIe1`Nm\ ՊxȻo._U0@ b3֩C~ Nwۥ`LB=!hoWE%@8 W@ I{>DyplnQԌI3;b_T%z1@IDAT+'Cf;ּuvt`*Tb9Jla*zQ@J%F (9!leA9Ӻmm)*4HӉcx+`S1@63,4,fS{QJJ`NK_x$ZPoơtX֭{o\q$/šF1e)-Ǘ)7@?Ez56UiPi% 8:s8"Gr0sQ;4i&wqqk,x-CjurJu:,rG [$k :KUY#G*'+镝{-))Q]WgFԑE4SN-v\;q'ΟfwfKڦnzq/mL޻w߼ѓ 4O}w^~sm Jvzc@ {+以/vTN}wzMGDё^6kZKdHvٽ})=yL߸VD@,êՄ*ZӍЁ}n l cAIL:ՎNKx322T +Xv , aZI{xQbê&ì`nu]iJ/x-)|xy\Xm>\Dň`eJW0aF^& po]2zLZKր;e S?unKSuHnڥ|v2z b 7vmce,~zAWǯ?W*IX?z2I L};A^24[U]k-L1FHdݑ^Dmyˎ4k,|,(EGImƌ Z`˪0PjoXѺ ' (8WtL6.}z925mF`M Ӽ\gՐ>#jdFրր`i]Ot |rpߐkޔ\v5EƍE0-, ȗ?7?ٵE,$} zI(ڊl<*)viZX;T?lCQe6'a-ͼ~D[P.g{Hlhjf3F*խ1xlu ލ[]8%ќ Ofp# Du=u4_W_~F\bh^ffoa&;i4qDzƠ۔'vI87q u N׺ZuY9K |/;*+x*6&sDۭy(Rk[寫zx s,es.cfmjnum}fm nԾƏ ;9V&$EmX5-vf Cu'q-jXmgC fȲK ؟σI/Na-<] ٿ4`W`r]FaeoS?[^*A|ݲ {?ܷ0,.JC:[*ċew+2&Dh=}M (rɧ!wIZ;UŸfS}>!cr4KA-_ sj$oWɇoWn>cR,BʎXMX7%2; NK'ɰjhsp -tdlj8?vXi ױ8Uwa.1WH}X|U߆gfL$EK"$^WҟYVSYkF'ѦbS.^L8eŇ$^0p&֝<(bh-/.2W(3! ق+?ZB5hzw.ݼ,d:>1976E/6hCSi6*Pc_ۯmw< 7~L4hm$IPr}y`d r#rp]\֭Y!ǏwBDR `G`6*l_> |`4 EpLu'NPSssr)<p8p_7f_x2OffzQ >>/̷E eALt#Z<ɖ2w\u999dZ<4 RQQr%7czb(l:BNJ s4驎i- Y#%1v:ץ@Q;@?2SG 7CJˎAMN%1]b]2Cu GA2IG҅SII"aht 'NN3—]y\~9s:<.'xG ՠ$1TQ"F\&B A.BEtkihfRY"_*W/e'[t w6 w;Cg",E1;wl]$'=d~4*v2|,u%!;0'ǮC16OI: w4x^lП׊&K/GlG `J8wѢ55504ھ`|$UHKKl{=9TW^2b-}V.r8%Ƞy@$By4DI{Ey׋ga,)?$ h){9`} htG \eeeɼy cZ;q?8E '-p 4p)!Gf9?+K]=w;/7< ;&PWl_&RIL?ᒽI<fS|^{焼$s1޹7o\ku Ҙom73Z,lZ#U}& 57.ssr4!*{Br1$5ޠ4U>0%۝I!3SdR] Ҁz uKJ/ׯJ|#x^cqO2]_v*n| G)7>f-2IeSk h h h%vK{AdͪemxLfϙ: ejĠ© fcO;+_Nxh"bb̦Z8Srr?@ipL2chA\tIQVo;,ˮe.v{ ?|FJ?Iq"&4۶G|a $`%;]{Vl,Ĉ;OuIK%U=*mmHc "XOyu= JT{26 vvWG#RډxCY9okө%aA² `l=8?I+W~P0q/ *阬Nx<,2_˵U,/ R?VA?vc{T$#I$2F6L1K>ɽ~FvlkdR^^\be8.^8p@)TbG=R:{g۾}Zv i>i[ݰ!1¨9BPhn:+LRr]yU=)ބxPẁFŃby)(G:?x ղvy併+R_?lYl `̋˭qc=*ǵhqyY KH%'5̔U˾8]r͚5KOGƽc6owZҌg1"=蓭XJhH{8{8&j)o)ƞ'nI'Ϊ3}t+voU3:!$hCǩZ;ٷo>|X1x!x E/qZkkTadڌى+54g:@pKC8}8蟀[].sܹtRߪE27-+rss Ǝ#t8R*UZxdˑtzlv|X\ čPFN %l[BC h8G&3}fhʮ]q=8ѷ6 c [F%3 oma>;L)=h=4@7&ZvX );o˯Q{Ӳ+շ8hgd5QT B2s9od{{wPWސ ?j*P=d˪ `'@:nVA555td!|l茂qg-=P˶Vd߈qbc'-`"C=s+tk].4sl\">T#X,(>o&yO+͠I8gx#E⥃  OA_h $JRGJP\ŋWf2d {%%Z9;?t7ޏǡEC`J` ⩶=I=%+&Vɧq;B1\]q9 JZ[[lZ{&~3¥uG3yR-ـD`s,2h+U@!`jaCX]mU3ufWe 9˒@,x Zyɋ䆏'nL<l_9+g(:=TV&6 B dE{k լuUd¾=ƓH W2-j?W-I~ 9Po^m l[ƽU_ڛ1V k-a9#5$ ^b%Ok]iZ6l6Fذav!0GIuZ1qF7eCشrȲ/rٲe5D:Jt}zl8SU~Cn4 @I3,z^|ݕr۝=<Qo-f<bI⩩N_~Z[ 0I44$6–!LC'U7A>բ.i.7QbZ>5U,e ` `N"ॵ8Y{UIBYZpǸ5$zi'ɉ:z ۙ1jM+F7ȁݕ'/)3FPa6F"*Yx/h-5Yggint*M능 փ dqu՝-DiDՌD 621TzV$,:jsGBsU]2#.n|7̆fE AϠ:M0o%SekXjCc{yNo Sު[Pow-"-fϞcҩl(3e]&7nP]çoz:gրր-x6'k7~WC6';EPcrI$$Zg_a-~ҙ7\>{xvj۱n ѺG,Hxܘ]s.40?K *Њ/;&ل0ۈUՆ-/0Jx3~2NXP!^^ٷJx|\sLI 6F  ]-% (s3sbi"Pc rV$ UR|^AE8PNqu~Ҁbr჊xb:;V/L8@ 9iwΪbxwgOO]c:垧>Np$#B%@Nl/8ԧLqܐM>%횁"}puΜ9lvu̙.bٰa)ޮ ^LAwAS.})׹EP.H1>_ V!~+rWa"q#ɛ+^_x r_X](\l~Mkk`>lт&C4QzF81 V9la;]d"ewН`CDk'Ʒl + 8p@ TMHX#y;R[#[W;gV x >ǁr`zVDݟ hhĴx[uT 58qq[pK[MX+c V$`ZRZ܄YeR)]#kU "h 8nVZU>WF{dJZ)f0\N. Y)wMfH{ 7p(Xh:]? oDn KM%|`Gel(3QFo_I'kl8?^.Ry:M‹<ǗIFeZZZXdh=C@λސ=pŻ'`LĂ}.Q SXvm"a: cPw\y;"Reg*۷(۷&XBd1}V@5;]$IL #-E>WU8tjmmU9;`]]]NˆVNOUA6IOp ?mCC]q?ql!*ڵ hۯ[+\ w?_Ǝ(?)h|w_槮I{vhr8STc_[Z`ASxteItbixPsşCMK/l'=m㗄Tgt˝Ϝ\]6TF1s&~H"q8 В}u6!lhbY2h3 pp;Ɩ`\'&t]pcYcրրր@4Q_oJd-#Oͷ WQۃ63͆JY@ǏӤIrG[_ ʁ #ށMYr];eWdݚp^XY>x ŏ\㮄s*'DIKb0lǙc{K Rb`wQbGW.u{҉:V{')6pkƣge &5H`jˁݔh|b,v7H>H~ddVu˚=!tJ$̥5]wADmn HUeTlrp=T+ ZBB@e3`lr8q6RZA (|UH3qe̬ⴍX$n"=);k" )@8 vp `8 h :8n d։xbl u7o0mt磩#G:;K#k`ipzZFhFʿ+T= d|_wzUyrɥtKY|~TWy:\f>_Vd֜*PFߌ ;3ͥ2|/ʛ]^rhY"1Akk3Eo8Vt b#KM㞄}7Dv}ѢEr竘QMɌd/))Q3rtLƯFLt6vk)_xu3#Z%K(e"2!C؊ giM$E sV!Ꮇrӭeed܄LʼeXn+o*`Bns':9tDST6I#b7ԷhBQ ,;S:Eoi  ©Ѩ]Rerj9]mԡ[#vdP2Spu#7(gddBfS磕)>Dn y CFhqQ[lh(d5P>6~)Wq*h h h h w+%߿,+_{Vxs>,p `p$jIJ%̚$]"o]̌ƫ{N΅uOP-15[ u:4oo<x[ n3jg7:KZtt:|߿`O@oQcm)n'p=şGc`E*KEQ]_=W7$TlĕP5t |Ef%%L kx !QD Hr~.qOaT:uA)lIYK:vQG$Ű7JT*-F3k?,VaqaC"֡7?5pvŪAӆy|Ol0(iޖG_ǵRk*6~Pl_h h h c /o?GJ>iۻCOE_+B؞#)cg ,jY{Bp{òX'k$T1!LM1}}Yzg VO$8u 9,c.m}K҉31~"IZN4%vBf nat`D>n0NŸTZptrJE( D`>hxi,-tsTYː,~gmy6#̃ETDv׆e7ȨM!y>0磂#*_Υ}p VM> O^} Yi3Yaar;MS3-R|;aѻG&q?05Pp(ikm?/_}~ZOl['LKhRNOj8P1b¨VX#q˧H<3FOӧOc /Ų{n)//J:-7& 1قY@%^vlG!ac>ۙlVa--ZZZCX.X/cEƗ'j6I*3^]tCᏕu6YS>"۪Cr)(uވx)QqUNVr0ԉM>%(>1ȑT6n/IMI'q$@̑]x1fdgHZ>)nvzox-)*5550,5RNBW^/er׽˝=,'LxP(GBu #f?8 gKMŴ6B44i\&LЕ4Hu$+eee]g#] a\s@)· ǰ5ŒkǁB8asI1;.m_; Bˆ+Gpjf'W\qdeelu[Z=mbOy)va|mh5tעEk@k@k@k 2 @ą><.?#pkcOɵ7*$!C~ݻh |gUR ,uuaoKfG0L 83ēy ɸNcy7S≤IQ񄬕,8 b( JH<,%4sbs5z%򩯃ZuRΘZWFud~_n K?Wj9j˨q*tOl`업AYuUθǀC<5D-$W$˚5kT0ӾPlLxn3{4`< iaKuYdZZZZR=|>PĥEZ<]ͯ?)ZBjX+ň\I#3!%##C.?œYW]~mٰa44 ɖ Ծe l7l29tzN=²qI]GeĎݱC\|6 #NJfVZO$H):7a}TBTjg$i0tmѐ|0?.G@үlF ˀPPԔKq"D̆EUee:4퐫K*vNV)QmNʌ uGk@k@k@k`X i4@IDATΌW[BZ[er46 `|{1g$b.xt]MlX\&Ók6f}$e׮]yfUWZ.o4W! *>X B9_6հekp)NWsd Ovian]+'_ $9όhw=Fo ԗfSꨖ-eQ7Ni%25Xu[%U%Blm򇢠xxr<44n~PVD`PJKK)k@[j6%Pi1EdNK籲?_ ȧ[ SNƄ\/܎>hMS Eպe=$;m7G fHZ1wjhF\0a߱=ǣ'Z>u;Y/~QY~|X6n#ϻ~`0e 3>0=*+04OH@7P@W 7{*,G>S$e;y\e\g44N>leh`9Jz;'`KMc A`\ t% b^T=[7\QXZ\BZvܩ'ֱ1aV6߁* u)M~ƍ\D=OZ:4@B͈opK4$cݹq^KV ts]*63I}~b')ȁV93=(d e 9ZsbcYUukz=0MJۢ Fa %.+"Rc!9ƽQwkbWWK4cq GJ%ۤX&\ =-*m|fz0t֑,MDKKβ C! :K @DmʏY$"1l x,IRGJWڷjT5#UG@Xa1ݵTŸ/q&AMN#݅}LҨ:n:]bEn8F` .Z44o/Y;Ng!5{lu]Gw^6OMMLz9RfqE!#Xq$8_FOz) `ďDrL s0l{ 0 AP{zgXHҊp)2 H8Mb FVf* L*@?fJG.>t$F+c +C X6/˗]O-ȊvMSGqtyb7 VR@ykX4%$Fu0wy{$~ \"t5d54?}.$뢵U&Uu&yc`=욚ִX@k%hH; |x  (innWY\꾇>¥t8ڪZf!tSeX0F'/Qb.xU)4w ͣ-3YB @\ >Rk@k 5`ʱF XLif.k)m%dܙ=V֪Dy `8C"!ca8he>1;\ZLz\zQ0vebPc4unFg93.yny{n<,, #z.@ 2d,^J [ H`y@x:_FʅhMLM>v".RwiҫO.{O 7#7,KUa ̛$u-[,hiiiS>!9]E:(!+7+n>\^^xћo?|f͞Bphf)DAˣ=K6̰+/?v;4^)@f2P̕&ֵ.-Z]4`tԛCVb 4m"gjEc~a\?1Ic˓Xl"3s=BrV6&0I}U$6^c  `&32Ys\pDLM̴X`bӊW@*JYHQH\0!=ڟmLuc-|O#; ɧu| P}oذA.hFF9˟OO'N`\<[-YyR+9xdQ_ g6$(iii6֯_/F"csg KX<\ĥw|]~1`3r!-pCD |X G%1`=~8LaSA34(x_Ⱥq FitgSNIcI@ P$d 5aEҫ Xt HNT@)UEVV\`|]u%k Sց9@OwC쨟3`Iə)25!3@LHѰBS X2!WH+F0f;坈'vlPċ&dȑ맀 _N<1JY8qMF%L% ,M6)%ӕ({oȓ}0 3#a:j9q K۞,zu:`%֭Fb(+ko#Eujh +5$'h4b+/+q'ߎx}:p9FcQ!'h:RZJI> k0\|(]2ƪ@OsH aQK`&JZTH $FB x~ ?0wրրր@52?^fJ;Z~-g#=u7b-A V2&RuP9<{e%0mN Z@#\ϭv7LJIA9AH\rZ[MSc%]IbbBI3#8;8`J&1eǶ[*Z!a1`L&ƺTOrboFvhGd;52>2vXIMMUf'QrZ(w9qˆ/mYu@hTv1% U~oW/3LkGlx: Eˬ`0C Es}-ZZZZ4}gl|NxTVYQj_M$3+W&M~(^oɆ`(Ceݻ+`wI:qԱ>J#m+A?Aq 7exh7mp X Clw 5YI)Z9"RCpZU%D@Ve{uXD "CE9%*:QzÌx#6yxH~EZ:=ty #l{ӰŊBp-Y9"IY@YH 0?~<.c)>; dkORt̜( -RdS7qD{NN"y>~$***""i_ .l$QJB+>~D־?rPrrXn'I(62ȧ,ڇYװtI`c׬4<xpOņj`E>afߑɧ!P.v``]H_e'S%`5w̟b`I#`YaG.| zU5e![1^&J3!> 3Vj jN>ypجI=_#`EO#& ~'`'{\H<7NF2_Ơ" E)1Z3<&d0E08z:35iŶG.9 &S8SpzePE=ZM .P8$9 CdjZ>){S&PʒhRA@MaAآ25d'{ DOl:`u-COh4G@n"EF -Z&` )EB`@u6+MHJUHҦf, ,+۝>,H%t*bi9O4EeUYX> D@ךm3 `-rVsyd e֞ xK^x̚5KY#q{RPTTT$e v2kS0΍HLyyy2f̘x)mf̘\:dһ͝z55550 <Jۀ-$TSc?_koM}SM&ST5Z@l Ծ7PR tG^4`Ln {߳_*:ɖ-[+\ l1B,n[-ZD9ٿY]8c/-fϞg>$~()yzl^h h h h  .M sG$3oׯ3:ݵ+{N$ ) AKPw: &I!u1fnlZAx"ERֶt7M'a$,K|oD/چu=lѬ/Åx@Y81"Dns:AJ%el)S(WuֆXShvBSP:Onw޳kI nwǥwO~5 4Zxyܢ>{?`xLŸo'Τ0~lϑyot{!g/DZz ^@@ M>zi㋱ Vdmx%L҈nxN,"icosQ|eM9), @րրրh#[WbqZٺyl{e2HT{f#OkVF57†\9JҝN TɈS'f4Q?CɰaҲP, 7SŒjwj' gCv9Q4g[ |W@@#- a2F* (Z"ݮT^,[LiuSwb9jG9s)XZPӁ_'-ZZZZ#)QO%ܱuD`+^Q>蓲+,Abw-ZFq ] arDܳ%Bz`ϒlhf 0{Fw6يs T8m?i $Zz? @sZDT#SXR &D[p@P[g-g@+pt~hx9NOu.==]rrrnӲt$(xV b'VZd%hd %[땙cz( ;~YRY^"'H>&`s+b8BݝH-Ƽh8ƾ-ӑm}h!IH\P2 M޽߮"oƍ6Z"jNGk&o%6:(Z;xjZ:k@O1R°p  H0TqH( @ux~ ωT"MMMN#84lxUNT pDk $C;d㺷a3a: x|H3vc?eGA~qɱ%-#UvXu )hWjHw4#U-C9jLf OgU]v7h h hid\%_2ds6WUU,`-8bg W| 4JjsD$ U44I]2f8i .ܟ&TOaF1Z9*-xsFh --* bediSG[W(0e9y#3>`\Ioj⋾(`}NAЀ&AI|JNh(4H}}JMMP˥***qZmOP$ݢ4_iT nucdڷYf̚-9Y Gx Rcq|&Z;&38 b++?|t6?bfFu3%]2SgӮ{N,6(Mʥ2v@РFh hi>\"Vt c[MMJFFƀPA (T>?bHC4OiqإPˆhpH|z\{Dl#.GL'ILkUXJPA րp׀هq@ 8Pir^vvBH|VFvUV-yul_jI]7l\d@H$$nKIn.$$$$PB'lɒU,Yղ{YI͜hwhfgΜ9)3I2Ap 0#lrD*Ps$HTsؿ;z^IfRCi!y.̧80R|π;;)ݪ^? *OStc(KԾ3j<94R-mцd7%*m1)a:aa&0 |;U OJ sb)jש1ƎJҀ2@Gŗy0&`&`Ï;%-qV٢K}E6-~ZEYWOL~l>>2Twv7LgMQYdo"79FvIO;6UT .Ϗet&ƶ2CE}74J{~-='"͐™.P 6gkjRSʓg3$A00{P̥/tE[6]R͘Q˂|/LPzÏ]d?1tC ij@>VU1pV`PtwcKjҽF9F2zTaWʪC'{k0l>=|nǷ>ٞn+d@F_ᚻ{Ѐ|ԩ}P%`9LL' Lg ҬtϴshsOD-:ieӦ `ri\vh_8HOdTwv ge4#*ЙOISoU f ǥEʲˣD0BGɯ)jGI)Ȃt p6F>4 ^gnʔ)?giqqq4}Pșg8.ia&`&0| g6ϙ+%Cp&5/.V\qQUuMTVV,ԡ Vw?p |4u DkDO=QYT5k-[Qw5] aŅ>] OFet jPOT\xj&`#ͧ?b4ǪGr8'hBN mL|`FB&00aN_~PD!{XھecE.9sF4TS{5+:,z">C \ `]!'%4)(% J1 PEƶ-Q{_93]x|%PQ}˦K}Ӊ_0&`#ͧs'%0ȀˡOgÀ/K00aG{%&"K%CttG[l-71fK ʺ) BSGkrꕝ˗<&=jD!Dž'@Zt4G&DRr$:FDwEز92#j40cyzԱ-LiD5ُy'0%/ &=) $f (Ȁʳф,xlPK(]w _F"ӖJ%*ڷn|iW8i't0;z֮ZgsͧU LZ;=KWF]Ur@FA$ tƻ:dBV.p\~ޕG='\xLk0l>;D ҍRƀgJ*΀jVcں:~M ,PZ"O&`& E d@UIw® lyyƣ}XͥO0ϟޚ|ZlaGu wUI ҩO!osqxl\w]Ɇu{0Ygqe?]^7QW7^s="en&`#@n$cZBHBoDO 9 MLIL`(p a^I3K8 Z[Ư~qxc9EǏM$'M]+|$gҮxe(Dd>B/mj:>^O>L$ fΪ.[E4]-H쨭uWX\O;rXVU}TޓRUQT.hnr \􎲬Σ=RG(,/SшhXBU=ee~_=|B0HܩhHMz}R ̟K.$*..2RҐՇŷy i00/\>oX:?zBt9t dт_*+'DUUQIYq h+/ d)ml>dTSK&GeŗhDZ#@2Hʀڗ#q>ըl}WpqbLб9m<ʴxVyHҥL`4v0 }6H$<0jjjZZZB%q=8X|CԴibrĩ&`&`Eq[~)J){?xk+Ѵ3 'lX:|}K;$"@5RQRŅ2Jٲ4vֹ% :i[һ8)"yasR{^o&'O}bgIK?/㫾^,j4P<щ|`qtD)LL 8%x %~1/LjD{{[eEOEO4(+jƗܖ̧ËɤEIeFp e>QEWH%‚⨩sgy\{GP*D]z=!PJ[qaoQL 8ل_&'O}b񍯂M)I|0>%qCsq5eʔP 5K:nN&`&hP͏I:[Œ P_)y$%2|bcIYB'YŶ%x (H'Tu&+3fV]eT9@]2ѥW:]9|LdkteytgёowꌆM22p}8'l>^I&TK >€PMȏ;Mw%lLL  ~N cK4 "|l1H;12=;?%3m*dG!ض-N(Ҩ2J&08jJT ɀҹ.uwl?og)(PN_yՏ\@o=G'~_FGAd<+xGZNb @;.6#g!-c; 2ʀ*D"z@Qwwgb"[Nǯ00'/%ΌG\i&6ߕ2?cYlRqaE4NCy,Ou((;wE2)B靾V)L}|R2C(j P! Xgk𸂨CI[Ǟ+%I-|}ƀ.l3mpc~6}Q}U?d7\ʢ^(vC6p&邡{%\/֞w axܹ3Zvmcj10 q *e L(4H2Ft1|0/d4*)M(Fttx٥wYib4l %"2YErl,)ω%5DWwEK='~jXo^uJ/ >6ʜʬ:['MJohj|2m\vJ EE̹ܒ7]huP׻uє{v~$i`xZitZJ8Lͧ$=}=LL PSZ-UKs%>Óf{ۥTVE*W݄p.vhBsW'5+1hl߮һF+ ~;*h1RԢٟd,T3"vuk,U'CדZ;F{IQqEFo2e=nP;U7n\{Dg )XԶ3jjK0jՏi]5j5{/6v1Σ- # C߮Ǐnh̙/l? s҈%ʣ_@7:Lͧ_dm6IWH3НRee@ 4]c)3xb|G(܉O}X4P{d=PcRDa:Y2Nbh[-ӱh[BS>~G%H) #{iי)`*ASP:Y{dfz*z)C%>p̗ZeP 2v#G(DF#Q׾^KX[ԩ,!JB-'M1ReNY=]G_fRx)Z& 6M4Q`;{ # ;vltwF555ѴiӢ3.$s5!_msH2DGeyA׾/W Qy>Nqn[lrYfEϏ***BAQD)]gO]8c`ab ҵK:.3|[TX QELRts`=ÎNN6rئ;#z_ӧk:+5=acYݨlZ|L`4w4>vJ{%Մ0jhhtZjUtM ?'}BsK&`&`&0Lv|XxM*21tF4uܽ+t$>Hv!e`)uĻ>djx*:ִ┲'134韥gJ}MGȬ9Ը@}u Md >|!CiLi)zHad_(WT\LyÏogώLf ARye%S Jq մz[!Ylc8aQJȀ*-1ɀ\ z$j2 PTxZ} :F7Es]&Is.8왚Π9%^~uc_\i8 U&`RZ|:,c| UjUQ2M狟%׭ ?S[i:;1IDATVz=dl<]~a%qDXi)&cs(#-+VGKG,`uG2Jfi}uRXĉɃكQF3oZS(;LfD $e= y -;1jI[Enl]MvK+R% ns^h$OyHJ^Z)qz "gK&޴M'ES/&LUq$I&RRS2:T]L.OHǔOJ[BO#:!evԪ\Y͝j4arL7^@}m0dtiY#$C&d3릛nڈ/'NPVQ4AT^3=v#L12o^D]w] À޽;jnNMUzWY:[ZNRIZLuj6U 2}3*NK%rO++ Cz~D,J"e<=,owv]-_]ZT)*aT}P3ƌV2J*-Z6eV~g$K!42 R Bi\o~Z"MF-χ3u̐ + NFqCL{Ch0& ”GuVG{8^('cvpڕQ$_v%=ڔD+XcqY.Ұdh񝺩):#aʋfŶ:V5z\b ^l %k z qWcvl\&|l/vSs{vmai(*Ap@> Fmg|gBs q'Wgkzik҇/I;O7000^js)ݐY B)qftiiT۸,\)tTfRF*mz!Uz 2Nj5in G+"@dWj?#HjةLGTeM3vaT1{BKeXdMp2RRzQqm*&טo~Xc0 kL> n \dK,FWZbfC/bnTe?],I"z5=?$3m`1^fR*B9E<*<6<^Bz^ o0`[vjPiXN6rłx]22d?Wijl :/]ҵX2NꝹilTaܯ}kJ=puͲЩ(J2Ȁ*1sXOX8?J{ǥgTSG[2)ld[a'CE'J+SFY05ged?Dd/^za8m~A7| =Zd>(s\ҙҡ~;ҼP&f+91Lͼx}\ve̙y .+zHo QAqH:ua&0|~dmT@ˉ/Od;Sw%>|&`&`&`ßF20N 2"2eDV M)b}mC1<6 0!9ce4(R`l }[aH8Cb۶m޽{Ę#Ԁ IdU`DG&L1(s#I-&}2ƅ^F*K Ê%㥗^,Y˽O3G1b0x>&wX8Jġc$$&2T T۸XM3F_I%@=/= IO2Ԫ#j*d4U yI/2ddp ĶčS}ڔ%p+ȴ(ai/K_طd<+a \-UJ!e4R^оIƕʬtBYOInxd,)$wnĸ1snfKtH bL:tgT((]RI g lƔ=q jhY^M.-f]Ahخ&4/R6gIk'/9y:&^&7N8vYҸi)vܼVIܒ R,)#(kQ¢pǦ+. [Nؖ3xyܪ`NzYٰ>vkI1|̞Pp 6W )YCо|%I|Ca&`&`&? ُg?X ?#LZpb"?DEK8293 -br$6|b&mBZSP4WWW͛ O00qfCu?Y(l;`dzp}4L2&+_8Sg9Uz~0/ƘP0-1#oSz$ 22[6!q'dzs'JAmjSЦ3uyRKj58t*UKS|Tmۃiө3eKc&HeYwu0N0s&vv5꒑S"XL3w_1}q#22Y\ >*_<)|'f8^wzigݎrVJV]]]Lѯ?E=)l^ 5հ(I=Ѳ>{똖drzԩSmHn^r|e,Svns !̛>#_,Ho">Ǥ-LLL st^ϥH, 1217YDJ4fIV OI!?־20L$)5=YJ0b%8?FK.an>y^LKyš4bNnjd.DI_ IGZoH!kCFO*)e兡AF L`yE">O*QlnߧeB=Z~08j~u'!wt38d`(JRݹ@K/]3g0QWϨl' C }3PXDZXٶߌk𝘾eMmd<5SR鶓rQ&YfE+tY uLO;5sn߾= 6Sy-ń"#ub$g˜vJox:(5K0 @o`t|^]Lm_% @~(fVI(a4}Z"yn.<ę0^J36t t-D0 X"3`܇ԣeΒq%0̎58M'L;vr[fJ2(PCoqV7*ceLr;3˟z|㘼$1pX#s!\iU} NFH %02* S]'NH_I%^.q !.fi D{Qx-{NjIId a@a`c`t2ժs10koJ3u,Ax`c_句Ӭ 9bJ)_mK5Y&N:tP00t1ų/F4gQ9:K6Gz{C&$a 4D4gDok|hߓ_r L6gIo0">%[Q(e:ō)aD26laė, NhjժχAD(fLxiM`9'>ʊ+¶`0tPo͓g貜 %ڗ76KY d_&`Zč1!00(gdkfM'6 xooK ~dͪ*]M( b Cr}kVm0)*]D_{qMb2&YLT.pG0! c,q=l4 6-Z.JLPJJq}]#S~ܨ?*q}w$^R~yDb=_o4)X#ӐrÇ)zAL˝Q0&>ϒ7{x}I'UJjJ0L #DL._F -,`}葵`pܥ9<"̺\/IwI%~9YNEyP 6`bl29]"TAvɽcc!dݺua3Uk 0tK+a#rD2RP>```4>XL/ܤK?gJo&>ӆ -L;.DZO11(A2g2H1aqy]$ ?8^1xӍJ0V =hc9}hlBӷYH}z00000QELk% 2JLPDꈾ+d;6˪ɬ$ F"6 @tM LtMwȎY(02tH#Mf[h~N]MMMئS*CLt)[~}(1xޗ%&_ٙN;J5y<3zSa/i] vyܥƿ~N 14Ȇ/c,t`fWzNJv0kIHoO]pabΙ3'692vb"YZc|Pldݗ3t5=CuLl35x]r<=LDGrֵMOe;A|2&0 >G8=B0000'0U/@S &t bАYY=lpb1I$sMd81a>ͺitT =kt`1Wr &4frOe<1e 6m)$L zE1~TB#{'d dڵ[Y YcT2`jk8Aw˖- YbYMF\ls=L)0h| U]] sE"6.\gPط7HPD\ Pd{aűD^f$ZK %8lǘ h\.aDT>&&d9QVd`1Apnq; DV19C!  UK!Cl0ٽOSiꫯnPr$q1f0iȦ ˊ]_(a-20~qd 0G5g̚3_(a:='5R]g1o޼)8cW^y%__I#Cf%L R2 ES|_nXd9 ]־~P+c@jC?Ko*^AY?d!ҏzp/ƏIk׮`bBpګH^v 3X֋ |Ln1#"LrbB>NL 6k3C\Hxd/)]Ӌflnl\lDS+~ڈn4aqF-c@t2ߥǥzi(ZO^;" ƄG72Ǭu*ɺ}^-Tț 1;`Dwnc3Q6r8>(}O:_#:O„/e DZ CO?L,%D6ԛ_B.300b^SL}\gyzo&ÊLE^_IW |$/b&`&`&`T oJwJLPvF&J|1\bťrq_&&Omʙeg+oRZ,D\-[Y5R8;ev9r{d(A:e>%7K~i c+ )dX#/>yfCelB~EO(2)brO)L"a&0O]&`&`&`&0 Apk JL0a gSM7&jL0)j"lDi2Z0lHlZ*m<8fVKtIS%Jv[33^.PSRr2Xn[ץmPr$%d-{Slۉ7dd]|tTS-?>1ڀ]v`З&ޔ?e> m^<_K؞#J!#L8A1S%Rd<8Oo?>).t\'I4ztJ` ..ca}k3 f.1г.7a2?,aΝ'aOSCLLLΔT=0iR{!f4^L& Mfz31)#cIjp80+iR.]`R%c#+I*؜aX),'w@5it>[30>-4I6t3`rqHo~c (uk/:wPk%;`IAd:0'>+a u\'4>~r301hM(@#k:˜o=p1Yh[xvxgJ7-]&Mx]F9j̀f7nss##̨'M:nz S?g۽&`&`&`&`'F/HK%R&`qs.Pmrd11=rH(ˆ,' >&%ZZ)m|00/>TZ2^/}\bš`Iݭ&-L<||̇{ / ͈/IZ=d60o9ddOcCf͚0lZ?Ki#CXϛ7XYdIxhY?0NH"*0x'p\z6^& Ms Ez'$^ӼƇ[utkRtJE'ML~QT1F#x֭lX?y %K%&0 |ջ߃700`VIohM RZwUWl'29laFA If%iD' I*wK(, 31 ' ˻A9]gCfBLw&x2:ϟ2;w&0 g'JIJ^0Jo-a.8I]Ŕ{T@k (L80(V\8*O!i;.+dq-Z(α aN~V" N$F<&ctɓ'CɌ"360oaA,^GQ}߲=ԣB cF 8FOo{&`&`&`#_#aB`:UKR&D1~8C?K-d`8&1:.մ\tZ+02[0 R(Alh$^NL*pjXh#="a m9W`u g7K& D]K NG`X|B4qqؔXxqhTMibˡytoK kxYPY `4KP|0Ux$ ^n \:%;`AF#uy=rP I(L*LlL}Y pf9LW5 1 =߇I^s7[e"i_j gLDMi,Y@r&?.꣉8B&?00ۆsFL{7Lb:1ƜUץH%2'@ YCdw}!^i ,F_pmR)d`_Y%fd>~A{Wj]fEw\ӘM /$Q9#&R0Eˈc&`&`&`4\@2ql¯ g%C9.\¤ ̍!&|HJۤ|0e@gLʁ0A0PoUѬ;Ojɓ\A8˸WgL`*Z€{6 ^KQ5 QGV\k9|1s %Mљ2ҿIo0-0?.zy厓_0@0!ZXNIengFnQ u9 #-WRgQLΝ;7'%)-)c*sŀD1M~)#ft000000aJ`Wߗ>/DfBBנyKkCJyad|R:"%ђTVPRg>sR1Nn Ax|Ix&U (%ٓOQ>6]kIdNzl^׏>a&`&`&`&`&`&` +1 M -> M; addrA : associative add; (* add is associative. *) add0r : forall x, add zero x = x; (* zero is neutral *) addr0 : forall x, add x zero = x; (* wrt add. *) }. HB.structure Definition Monoid := { M of is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r.math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V2.v000066400000000000000000000012641521677141400235720ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S of is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.structure Definition Monoid := { M of is_semigroup M & semigroup_is_monoid M }. (* is_monoid does not exist anymore *) Fail Check is_monoid. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.mixin Record xxxx P A := { F : bool }. math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V3.v000066400000000000000000000017401521677141400235720ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.factory Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.builders Context (M : Type) (f : is_monoid M). HB.instance Definition _ : is_semigroup M := is_semigroup.Build M add addrA. HB.instance Definition _ : semigroup_is_monoid M := semigroup_is_monoid.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples/GReTA_talk/V4.v000066400000000000000000000032751521677141400236000ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record semigroup_is_monoid M & is_semigroup M := { zero : M; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.factory Record is_monoid M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : forall x, add zero x = x; addr0 : forall x, add x zero = x; }. HB.builders Context (M : Type) & is_monoid M. HB.instance Definition _ := is_semigroup.Build M add addrA. HB.instance Definition _ := semigroup_is_monoid.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.mixin Record monoid_is_group G & is_monoid G := { opp : G -> G; subrr : forall x, add x (opp x) = zero; addNr : forall x, add (opp x) x = zero; }. HB.factory Record is_group G := { zero : G; add : G -> G -> G; opp : G -> G; addrA : associative add; add0r : forall x, add zero x = x; (* addr0 : forall x, add x zero = x; (* spurious *) *) subrr : forall x, add x (opp x) = zero; addNr : forall x, add (opp x) x = zero; }. HB.builders Context G & is_group G. Let addr0 : forall x, add x zero = x. Proof. by move=> x; rewrite -(addNr x) addrA subrr add0r. Qed. HB.instance Definition _ := is_monoid.Build G zero add addrA add0r addr0. HB.instance Definition _ := monoid_is_group.Build G opp subrr addNr. HB.end. HB.instance Definition Z_is_group : is_group Z := is_group.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_0_l (* Z.add_0_r (*spurious *) *) Z.sub_diag Z.add_opp_diag_l. math-comp-hierarchy-builder-4d8a939/examples/cat/000077500000000000000000000000001521677141400217435ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/cat/cat.v000066400000000000000000001157601521677141400227130ustar00rootroot00000000000000Require Import ssreflect ssrfun. From HB Require Import structures. Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Add Search Blacklist "__canonical__". Declare Scope algebra_scope. Delimit Scope algebra_scope with A. Local Open Scope algebra_scope. Declare Scope cat_scope. Delimit Scope cat_scope with cat. Local Open Scope cat_scope. (* we assume a few axioms to make life easier *) Axiom funext : forall {T : Type} {U : T -> Type} [f g : forall t, U t], (forall t, f t = g t) -> f = g. Axiom propext : forall P Q : Prop, P <-> Q -> P = Q. Axiom Prop_irrelevance : forall (P : Prop) (x y : P), x = y. (* Shortcut *) Notation U := Type. (* Base definition : raw categories = quivers *) HB.mixin Record IsQuiver C := { hom : C -> C -> U }. Unset Universe Checking. #[short(type="quiver")] HB.structure Definition Quiver : Set := { C of IsQuiver C }. Set Universe Checking. Bind Scope cat_scope with quiver. Bind Scope cat_scope with hom. Arguments hom {C} : rename. Notation homs T := (@hom T _ _). Notation "a ~> b" := (hom a b) (at level 99, b at level 200, format "a ~> b") : cat_scope. Notation "a ~>_ C b" := (@hom C a b) (at level 99, C at level 0, only parsing) : cat_scope. (* precategories are quivers + id and comp *) HB.mixin Record Quiver_IsPreCat C & Quiver C := { idmap : forall (a : C), a ~> a; comp : forall (a b c : C), (a ~> b) -> (b ~> c) -> (a ~> c); }. HB.factory Record IsPreCat C := { hom : C -> C -> U; idmap : forall (a : C), hom a a; comp : forall (a b c : C), hom a b -> hom b c -> hom a c; }. HB.builders Context C & IsPreCat C. HB.instance Definition _ := IsQuiver.Build C hom. HB.instance Definition _ := Quiver_IsPreCat.Build C idmap comp. HB.end. Unset Universe Checking. #[short(type="precat")] HB.structure Definition PreCat : Set := { C of IsPreCat C }. Set Universe Checking. Bind Scope cat_scope with precat. Arguments idmap {C} {a} : rename. Arguments comp {C} {a b c} : rename. Notation "f \o g" := (comp g f) : cat_scope. Notation "f \; g :> T" := (@comp T _ _ _ f g) (at level 60, g, T at level 60, format "f \; g :> T", only parsing) : cat_scope. Notation "f \; g" := (comp f g) : cat_scope. Notation "\idmap_ a" := (@idmap _ a) (only parsing, at level 0) : cat_scope. (* categories are precategories + laws *) HB.mixin Record PreCat_IsCat C & PreCat C := { comp1o : forall (a b : C) (f : a ~> b), idmap \; f = f; compo1 : forall (a b : C) (f : a ~> b), f \; idmap = f; compoA : forall (a b c d : C) (f : a ~> b) (g : b ~> c) (h : c ~> d), f \; (g \; h) = (f \; g) \; h }. Unset Universe Checking. #[short(type="cat")] HB.structure Definition Cat : Set := { C of PreCat_IsCat C & IsPreCat C }. Set Universe Checking. Bind Scope cat_scope with cat. Arguments compo1 {C a b} : rename. Arguments comp1o {C a b} : rename. Arguments compoA {C a b c d} : rename. (* the discrete category on a type cannot be the default, we make an alias *) Definition discrete (T : U) := T. HB.instance Definition _ T := @IsPreCat.Build (discrete T) (fun x y => x = y) (fun=> erefl) (@etrans _). Lemma etransA T (a b c d : discrete T) (f : a ~> b) (g : b ~> c) (h : c ~> d) : f \; (g \; h) = (f \; g) \; h. Proof. by rewrite /idmap/comp/=; case: _ / h; case: _ / g. Qed. HB.instance Definition _ T := PreCat_IsCat.Build (discrete T) (@etrans_id _) (fun _ _ _ => erefl) (@etransA _). (* the category of the unit type is the discrete one *) HB.instance Definition _ := Cat.copy unit (discrete unit). HB.instance Definition _ := @IsPreCat.Build U (fun A B => A -> B) (fun a => idfun) (fun a b c (f : a -> b) (g : b -> c) => (g \o f)%function). HB.instance Definition _ := PreCat_IsCat.Build U (fun _ _ _ => erefl) (fun _ _ _ => erefl) (fun _ _ _ _ _ _ _ => erefl). Lemma Ucomp (X Y Z : U) (f : X ~> Y) (g : Y ~> Z) : f \; g = (g \o f)%function. Proof. by []. Qed. Lemma Ucompx (X Y Z : U) (f : X ~> Y) (g : Y ~> Z) x : (f \; g) x = g (f x). Proof. by []. Qed. Lemma U1 (X : U) : \idmap_X = idfun. Proof. by []. Qed. Lemma U1x (X : U) x : \idmap_X x = x. Proof. by []. Qed. (* a prefunctor is a functor without laws *) HB.mixin Record IsPreFunctor (C D : quiver) (F : C -> D) := { Fhom : forall (a b : C), (a ~> b) -> (F a ~> F b) }. Unset Universe Checking. HB.structure Definition PreFunctor (C D : quiver) : Set := { F of IsPreFunctor C D F }. Set Universe Checking. HB.instance Definition _ := IsQuiver.Build quiver PreFunctor.type. Notation "F ^$" := (@Fhom _ _ F _ _) (at level 1, format "F ^$") : cat_scope. Notation "F <$> f" := (@Fhom _ _ F _ _ f) (at level 58, format "F <$> f", right associativity) : cat_scope. (* prefunctors are equal if their object and hom part are respectively equal *) Lemma prefunctorP (C D : quiver) (F G : C ~> D) (eqFG : F =1 G) : let homF a b F := F a ~> F b in (forall a b f, eq_rect _ (homF a b) (F <$> f) _ (funext eqFG) = G <$> f) -> F = G. Proof. move: F G => [F [[/= Fhom]]] [G [[/= Ghom]]] in eqFG *. case: _ / (funext eqFG) => /= in Ghom * => eqFGhom. congr PreFunctor.Pack; congr PreFunctor.Class; congr IsPreFunctor.Axioms_. by do 3!apply: funext=> ?. Qed. (* a functor is a prefunctor + laws for id and comp *) HB.mixin Record PreFunctor_IsFunctor (C D : precat) (F : C -> D) & @PreFunctor C D F := { F1 : forall (a : C), F <$> \idmap_a = idmap; Fcomp : forall (a b c : C) (f : a ~> b) (g : b ~> c), F <$> (f \; g) = F <$> f \; F <$> g; }. Unset Universe Checking. (* precat and cat have a quiver structure *) HB.structure Definition Functor (C D : precat) : Set := { F of IsPreFunctor C D F & PreFunctor_IsFunctor C D F }. Set Universe Checking. HB.instance Definition _ := IsQuiver.Build precat Functor.type. HB.instance Definition _ := IsQuiver.Build cat Functor.type. (* functor equality is the same as prefunctor because of PI *) Lemma functorP (C D : precat) (F G : C ~> D) (eqFG : F =1 G) : let homF a b F := F a ~> F b in (forall a b f, eq_rect _ (homF a b) (F^$ f) _ (funext eqFG) = G^$ f) -> F = G. Proof. move=> /= /prefunctorP {eqFG}. case: F G => [F [/= Fm Fm']] [G [/= Gm Gm']]//=. move=> [_] eqFG; have /= := eq_sigT_rect_existT _ _ eqFG; apply => {}eqFG. case: _ / eqFG => /= in Gm Gm' * => eqFG. case: _ / eqFG in Gm' *. congr Functor.Pack; congr Functor.Class. case: Fm' Gm' => [F1 Fc] [G1 Gc]. by congr PreFunctor_IsFunctor.Axioms_; apply: Prop_irrelevance. Qed. (* the identity function is a functor *) HB.instance Definition _ (C : quiver) := IsPreFunctor.Build C C idfun (fun a b => idfun). HB.instance Definition _ (C : precat) := PreFunctor_IsFunctor.Build C C idfun (fun=> erefl) (fun _ _ _ _ _ => erefl). (* the composition of prefunctors *) Section comp_prefunctor. Context {C D E : quiver} {F : C ~> D} {G : D ~> E}. HB.instance Definition _ := IsPreFunctor.Build C E (G \o F)%function (fun a b f => G <$> F <$> f). Lemma comp_Fun (a b : C) (f : a ~> b) : (G \o F)%function <$> f = G <$> (F <$> f). Proof. by []. Qed. End comp_prefunctor. Section comp_functor. Context {C D E : precat} {F : C ~> D} {G : D ~> E}. Lemma comp_F1 (a : C) : (G \o F)%function <$> \idmap_a = idmap. Proof. by rewrite !comp_Fun !F1. Qed. Lemma comp_Fcomp (a b c : C) (f : a ~> b) (g : b ~> c) : (G \o F)%function <$> (f \; g) = (G \o F)%function <$> f \; (G \o F)%function <$> g. Proof. by rewrite !comp_Fun !Fcomp. Qed. HB.instance Definition _ := PreFunctor_IsFunctor.Build C E (G \o F)%function comp_F1 comp_Fcomp. End comp_functor. (* precat and cat have a precategory structure *) HB.instance Definition _ := Quiver_IsPreCat.Build precat (fun=> idfun) (fun C D E (F : C ~> D) (G : D ~> E) => (G \o F)%function). HB.instance Definition _ := Quiver_IsPreCat.Build cat (fun=> idfun) (fun C D E (F : C ~> D) (G : D ~> E) => (G \o F)%function). Lemma funext_frefl A B (f : A -> B) : funext (frefl f) = erefl. Proof. exact: Prop_irrelevance. Qed. (* precategories and categories form a category *) Definition precat_cat : PreCat_IsCat precat. Proof. by split=> [C D F|C D F|C D C' D' F G H]; apply/functorP => a b f /=; rewrite funext_frefl. Qed. HB.instance Definition _ := precat_cat. Definition cat_cat : PreCat_IsCat cat. Proof. by split=> [C D F|C D F|C D C' D' F G H]; apply/functorP => a b f /=; rewrite funext_frefl. Qed. HB.instance Definition _ := cat_cat. Check (cat : cat). (* concrete categories *) HB.mixin Record Quiver_IsPreConcrete T & Quiver T := { concrete : T -> U; concrete_fun : forall (a b : T), (a ~> b) -> concrete a -> concrete b; }. Unset Universe Checking. #[short(type="preconcrete_quiver")] HB.structure Definition PreConcreteQuiver : Set := { C of Quiver_IsPreConcrete C & IsQuiver C }. Set Universe Checking. Coercion concrete : PreConcreteQuiver.sort >-> Sortclass. HB.mixin Record PreConcrete_IsConcrete T & PreConcreteQuiver T := { concrete_fun_inj : forall (a b : T), injective (concrete_fun a b) }. Unset Universe Checking. #[short(type="concrete_quiver")] HB.structure Definition ConcreteQuiver : Set := { C of PreConcreteQuiver C & PreConcrete_IsConcrete C }. Set Universe Checking. HB.instance Definition _ (C : ConcreteQuiver.type) := IsPreFunctor.Build _ _ (concrete : C -> U) concrete_fun. HB.mixin Record PreCat_IsConcrete T & ConcreteQuiver T & PreCat T := { concrete1 : forall (a : T), concrete <$> \idmap_a = idfun; concrete_comp : forall (a b c : T) (f : a ~> b) (g : b ~> c), concrete <$> (f \; g) = ((concrete <$> g) \o (concrete <$> f))%function; }. Unset Universe Checking. #[short(type="concrete_precat")] HB.structure Definition ConcretePreCat : Set := { C of PreCat C & ConcreteQuiver C & PreCat_IsConcrete C }. #[short(type="concrete_cat")] HB.structure Definition ConcreteCat : Set := { C of Cat C & ConcreteQuiver C & PreCat_IsConcrete C }. Set Universe Checking. HB.instance Definition _ (C : concrete_precat) := PreFunctor_IsFunctor.Build C U concrete (@concrete1 _) (@concrete_comp _). HB.instance Definition _ (C : ConcreteCat.type) := PreFunctor_IsFunctor.Build C U concrete (@concrete1 _) (@concrete_comp _). HB.instance Definition _ := Quiver_IsPreConcrete.Build U (fun _ _ => id). HB.instance Definition _ := PreConcrete_IsConcrete.Build U (fun _ _ _ _ => id). HB.instance Definition _ := PreCat_IsConcrete.Build U (fun=> erefl) (fun _ _ _ _ _ => erefl). Unset Universe Checking. HB.instance Definition _ := Quiver_IsPreConcrete.Build quiver (fun _ _ => id). HB.instance Definition _ := Quiver_IsPreConcrete.Build precat (fun _ _ => id). HB.instance Definition _ := Quiver_IsPreConcrete.Build cat (fun _ _ => id). Set Universe Checking. Lemma quiver_concrete_subproof : PreConcrete_IsConcrete quiver. Proof. constructor=> C D F G FG; apply: prefunctorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := quiver_concrete_subproof. Lemma precat_concrete_subproof : PreConcrete_IsConcrete precat. Proof. constructor=> C D F G FG; apply: functorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := precat_concrete_subproof. Lemma cat_concrete_subproof : PreConcrete_IsConcrete cat. Proof. constructor=> C D F G FG; apply: functorP. by move=> x; congr (_ x); apply: FG. by move=> *; admit. Admitted. HB.instance Definition _ := cat_concrete_subproof. HB.instance Definition _ := PreCat_IsConcrete.Build precat (fun=> erefl) (fun _ _ _ _ _ => erefl). HB.instance Definition _ := PreCat_IsConcrete.Build cat (fun=> erefl) (fun _ _ _ _ _ => erefl). (* constant functor *) Definition cst (C D : quiver) (c : C) := fun & D => c. Arguments cst {C} D c. HB.instance Definition _ {C D : precat} (c : C) := IsPreFunctor.Build D C (cst D c) (fun _ _ _ => idmap). HB.instance Definition _ {C D : cat} (c : C) := PreFunctor_IsFunctor.Build D C (cst D c) (fun=> erefl) (fun _ _ _ _ _ => esym (compo1 idmap)). (* opposite category *) Definition catop (C : U) : U := C. Notation "C ^op" := (catop C) (at level 2, format "C ^op") : cat_scope. HB.instance Definition _ (C : quiver) := IsQuiver.Build C^op (fun a b => hom b a). HB.instance Definition _ (C : precat) := Quiver_IsPreCat.Build (C^op) (fun=> idmap) (fun _ _ _ f g => g \; f). HB.instance Definition _ (C : cat) := PreCat_IsCat.Build (C^op) (fun _ _ _ => compo1 _) (fun _ _ _ => comp1o _) (fun _ _ _ _ _ _ _ => esym (compoA _ _ _)). HB.instance Definition _ {C : precat} {c : C} := IsPreFunctor.Build C _ (hom c) (fun a b f g => g \; f). Lemma hom_Fhom_subproof (C : cat) (x : C) : PreFunctor_IsFunctor _ _ (hom x). Proof. by split=> *; apply/funext => h; [apply: compo1 | apply: compoA]. Qed. HB.instance Definition _ {C : cat} {c : C} := hom_Fhom_subproof c. Check fun (C : cat) (x : C) => hom x : C ~>_cat U. Lemma hom_op {C : quiver} (c : C^op) : hom c = (@hom C)^~ c. Proof. reflexivity. Qed. Lemma homFhomx {C : precat} (a b c : C) (f : a ~> b) (g : c ~> a) : (hom c <$> f) g = g \; f. Proof. reflexivity. Qed. (* nary product of categories *) Definition dprod {I : U} (C : I -> U) := forall i, C i. Section hom_dprod. Context {I : U} (C : I -> quiver). Definition dprod_hom_subdef (a b : dprod C) := forall i, a i ~> b i. HB.instance Definition _ := IsQuiver.Build (dprod C) dprod_hom_subdef. End hom_dprod. Arguments dprod_hom_subdef /. Section precat_dprod. Context {I : U} (C : I -> precat). Definition dprod_idmap_subdef (a : dprod C) : a ~> a := fun=> idmap. Definition dprod_comp_subdef (a b c : dprod C) (f : a ~> b) (g : b ~> c) : a ~> c := fun i => f i \; g i. HB.instance Definition _ := IsPreCat.Build (dprod C) dprod_idmap_subdef dprod_comp_subdef. End precat_dprod. Arguments dprod_idmap_subdef /. Arguments dprod_comp_subdef /. Section cat_dprod. Context {I : U} (C : I -> cat). Local Notation type := (dprod C). Lemma dprod_is_cat : PreCat_IsCat type. Proof. split=> [a b f|a b f|a b c d f g h]; apply/funext => i; [exact: comp1o | exact: compo1 | exact: compoA]. Qed. HB.instance Definition _ := dprod_is_cat. End cat_dprod. (* binary product *) Section hom_prod. Context {C D : quiver}. Definition prod_hom_subdef (a b : C * D) := ((a.1 ~> b.1) * (a.2 ~> b.2))%type. HB.instance Definition _ := IsQuiver.Build (C * D)%type prod_hom_subdef. End hom_prod. Section precat_prod. Context {C D : precat}. HB.instance Definition _ := IsPreCat.Build (C * D)%type (fun=> (idmap, idmap)) (fun a b c (f : a ~> b) (g : b ~> c) => (f.1 \; g.1, f.2 \; g.2)). End precat_prod. Section cat_prod. Context {C D : cat}. Local Notation type := (C * D)%type. Lemma prod_is_cat : PreCat_IsCat type. Proof. split=> [[a1 a2] [b1 b2] [f1 f2]|[a1 a2] [b1 b2] [f1 f2]| [a1 a2] [b1 b2] [c1 c2] [d1 d2] [f1 f2] [g1 g2] [h1 h2]]; congr (_, _) => //=; by [exact: comp1o | exact: compo1 | exact: compoA]. Qed. HB.instance Definition _ := prod_is_cat. End cat_prod. HB.instance Definition _ (C : U) (D : quiver) := IsQuiver.Build (C -> D) (fun f g => forall c, f c ~> g c). (* naturality *) HB.mixin Record IsNatural (C : quiver) (D : precat) (F G : C ~>_quiver D) (n : forall c, F c ~> G c) := { natural : forall (a b : C) (f : a ~> b), F <$> f \; n b = n a \; G <$> f }. Unset Universe Checking. HB.structure Definition Natural (C : quiver) (D : precat) (F G : C ~>_quiver D) : Set := { n of @IsNatural C D F G n }. Set Universe Checking. HB.instance Definition _ (C : quiver) (D : precat) := IsQuiver.Build (PreFunctor.type C D) (@Natural.type C D). HB.instance Definition _ (C D : precat) := IsQuiver.Build (Functor.type C D) (@Natural.type C D). Arguments natural {C D F G} n [a b] f : rename. Check fun (C D : cat) (F G : C ~> D) => F ~>_(C ~>_cat D) G. Lemma naturalx (C : precat) (D : concrete_precat) (F G : C ~>_quiver D) (n : F ~> G) (a b : C) (f : a ~> b) g : (concrete <$> n b) ((concrete <$> F <$> f) g) = (concrete <$> G <$> f) ((concrete <$> n a) g). Proof. have /(congr1 (fun h => (concrete <$> h) g)) := natural n f. by rewrite !Fcomp. Qed. Arguments naturalx {C D F G} n [a b] f. Lemma naturalU (C : precat) (F G : C ~>_quiver U) (n : F ~> G) (a b : C) (f : a ~> b) g : n b (F^$ f g) = G^$ f (n a g). Proof. exact: (naturalx n). Qed. Lemma natP (C D : precat) (F G : C ~>_quiver D) (n m : F ~> G) : Natural.sort n = Natural.sort m -> n = m. Proof. case: n m => [/= n nP] [/= m mP] enm. elim: _ / enm in mP *; congr Natural.Pack. case: nP mP => [[?]] [[?]]; congr Natural.Class. congr IsNatural.Axioms_. exact: Prop_irrelevance. Qed. Notation "F ~~> G" := (F ~>_(homs quiver) G) (at level 99, G at level 200, format "F ~~> G"). Notation "F ~~> G :> C ~> D" := (F ~> G :> (C ~>_quiver D)) (at level 99, G at level 200, C, D at level 0, format "F ~~> G :> C ~> D"). Definition natural_id {C D : precat} (F : C ~>_quiver D) (a : C) := \idmap_(F a). Definition natural_id_natural (C D : cat) (F : C ~>_quiver D) : IsNatural C D F F (natural_id F). Proof. by constructor=> a b f; rewrite /natural_id/= compo1 comp1o. Qed. HB.instance Definition _ C D F := @natural_id_natural C D F. Check fun {C D : cat} (F : C ~>_quiver D) => natural_id F : F ~> F. Definition natural_comp {C D : precat} (F G H : C ~>_quiver D) (m : F ~> G) (n : G ~> H) (a : C) := m a \; n a. Definition natural_comp_natural (C D : cat) (F G H : C ~>_quiver D) m n : IsNatural C D F H (@natural_comp C D F G H m n). Proof. constructor=> a b f; rewrite /natural_comp/=. by rewrite compoA natural -compoA natural compoA. Qed. HB.instance Definition _ C D F G H m n := @natural_comp_natural C D F G H m n. HB.instance Definition _ {C D : cat} := Quiver_IsPreCat.Build (PreFunctor.type C D) natural_id natural_comp. HB.instance Definition _ {C D : cat} := Quiver_IsPreCat.Build (Functor.type C D) natural_id natural_comp. Lemma prefunctor_cat {C D : cat} : PreCat_IsCat (PreFunctor.type C D). Proof. constructor => [F G f|F G f|F G H J f g h]. - by apply/natP/funext => a; rewrite /= /natural_comp comp1o. - by apply/natP/funext => a; rewrite /= /natural_comp compo1. - by apply/natP/funext => a; rewrite /= /natural_comp compoA. Qed. HB.instance Definition _ C D := @prefunctor_cat C D. Lemma functor_cat {C D : cat} : PreCat_IsCat (Functor.type C D). Proof. constructor => [F G f|F G f|F G H J f g h]. - by apply/natP/funext => a; rewrite /= /natural_comp comp1o. - by apply/natP/funext => a; rewrite /= /natural_comp compo1. - by apply/natP/funext => a; rewrite /= /natural_comp compoA. Qed. HB.instance Definition _ C D := @functor_cat C D. Lemma idFmap (C : cat) (a b : C) (f : a ~> b) : idfun <$> f = f. Proof. by []. Qed. Lemma compFmap (C D E : cat) (F : C ~> D) (G : D ~> E) (a b : C) (f : a ~> b) : (G \o F) <$> f = G <$> F <$> f. Proof. by []. Qed. Section left_whiskering. Context {C D E : precat} {F G : C ~> D}. Definition whiskerl_fun (eta : forall c, F c ~> G c) (H : D ~> E) : forall c, (F \; H) c ~> (G \; H) c := fun c => H <$> eta c. Lemma whiskerl_is_nat (eta : F ~> G) (H : D ~> E) : IsNatural _ _ _ _ (whiskerl_fun eta H). Proof. by constructor=> a b f; rewrite /whiskerl_fun/= -!Fcomp natural. Qed. HB.instance Definition _ (eta : F ~> G) (H : D ~> E) := whiskerl_is_nat eta H. Definition whiskerl (eta : F ~> G) (H : D ~> E) : (F \; H) ~> (G \; H) := whiskerl_fun eta H : Natural.type _ _. End left_whiskering. Notation "F n" := (whiskerl F n) (at level 58, format "F n", right associativity) : cat_scope. Section right_whiskering. Context {C D E : precat} {F G : D ~> E}. Definition whiskerr_fun (H : C ~> D) (eta : forall d, F d ~> G d) (c : C) : (H \; F) c ~> (H \; G) c := eta (H c). Lemma whiskerr_is_nat (H : C ~> D) (eta : F ~> G) : IsNatural _ _ _ _ (whiskerr_fun H eta). Proof. by constructor=> a b f; rewrite /whiskerr_fun/= natural. Qed. HB.instance Definition _ (H : C ~> D) (eta : F ~> G) := whiskerr_is_nat H eta. Definition whiskerr (H : C ~> D) (eta : F ~> G) : (H \; F) ~> (H \; G) := whiskerr_fun H eta : Natural.type _ _. End right_whiskering. Notation "F <$o> n" := (whiskerr F n) (at level 58, format "F <$o> n", right associativity) : cat_scope. Definition whisker {C : cat} {D : precat} {E : cat} {F G : C ~>_precat D} {H K : D ~> E} (eta : F ~> G) (mu : H ~> K) : (F \; H) ~> (G \; K) := (eta H) \; (G <$o> mu). Notation "eta mu" := (whisker eta mu) (at level 58, format "eta mu", right associativity) : cat_scope. Lemma whiskern1 {C D E : cat} {F G : C ~>_precat D} (eta : F ~> G) (H : D ~> E) : eta \idmap_H = eta H. Proof. by apply/natP/funext=> c /=; apply: compo1. Qed. Lemma whisker1n {C D E : cat} {F G : D ~> E} (H : C ~> D) (eta : F ~> G) : \idmap_H eta = H <$o> eta. Proof. apply/natP/funext=> c /=; rewrite /natural_comp/=. by rewrite [X in X \; _]F1 comp1o. Qed. Definition delta (C D : cat) : C -> (D ~> C) := cst D. Arguments delta C D : clear implicits. Definition map_delta {C D : cat} (a b : C) (f : a ~> b) : delta C D a ~> delta C D b. Proof. apply: (@Natural.Pack _ _ (cst D a) (cst D b) (fun x => f)). apply: Natural.Class; apply: (IsNatural.Build _ _ _ _ _). by move=> a' b' ?; rewrite compo1 comp1o. Defined. HB.instance Definition _ {C D : cat} := IsPreFunctor.Build C (D ~> C) (delta C D) (@map_delta C D). Lemma delta_functor {C D : cat} : PreFunctor_IsFunctor _ _ (delta C D). Proof. by constructor=> [a|a b c f g]; exact/natP. Qed. HB.instance Definition _ C D := @delta_functor C D. HB.mixin Record IsMonad (C : precat) (M : C -> C) & @PreFunctor C C M := { unit : idfun ~~> M; join : (M \o M)%function ~~> M; bind : forall (a b : C), (a ~> M b) -> (M a ~> M b); bindE : forall a b (f : a ~> M b), bind a b f = M <$> f \; join b; unit_join : forall a, (M <$> unit a) \; join _ = idmap; join_unit : forall a, join _ \; (M <$> unit a) = idmap; join_square : forall a, M <$> join a \; join _ = join _ \; join _ }. #[short(type="premonad")] HB.structure Definition PreMonad (C : precat) := {M of @PreFunctor C C M & IsMonad C M}. #[short(type="monad")] HB.structure Definition Monad (C : precat) := {M of @Functor C C M & IsMonad C M}. HB.factory Record IsJoinMonad (C : precat) (M : C -> C) & @PreFunctor C C M := { unit : idfun ~~> M; join : (M \o M)%function ~~> M; unit_join : forall a, (M <$> unit a) \; join _ = idmap; join_unit : forall a, join _ \; (M <$> unit a) = idmap; join_square : forall a, M <$> join a \; join _ = join _ \; join _ }. HB.builders Context C M & IsJoinMonad C M. HB.instance Definition _ := IsMonad.Build C M (fun a b f => erefl) unit_join join_unit join_square. HB.end. HB.mixin Record IsCoMonad (C : precat) (M : C -> C) & @IsPreFunctor C C M := { counit : M ~~> idfun; cojoin : M ~~> (M \o M)%function; cobind : forall (a b : C), (M a ~> b) -> (M a ~> M b); cobindE : forall a b (f : M a ~> b), cobind a b f = cojoin _ \; M <$> f; unit_cojoin : forall a, (M <$> counit a) \; cojoin _ = idmap; join_counit : forall a, cojoin _ \; (M <$> counit a) = idmap; cojoin_square : forall a, cojoin _ \; M <$> cojoin a = cojoin _ \; cojoin _ }. #[short(type="precomonad")] HB.structure Definition PreCoMonad (C : precat) := {M of @PreFunctor C C M & IsCoMonad C M}. #[short(type="comonad")] HB.structure Definition CoMonad (C : precat) := {M of @Functor C C M & IsCoMonad C M}. HB.factory Record IsJoinCoMonad (C : precat) (M : C -> C) & @IsPreFunctor C C M := { counit : M ~~> idfun; cojoin : M ~~> (M \o M)%function; unit_cojoin : forall a, (M <$> counit a) \; cojoin _ = idmap; join_counit : forall a, cojoin _ \; (M <$> counit a) = idmap; cojoin_square : forall a, cojoin _ \; M <$> cojoin a = cojoin _ \; cojoin _ }. HB.builders Context C M & IsJoinCoMonad C M. HB.instance Definition _ := IsCoMonad.Build C M (fun a b f => erefl) unit_cojoin join_counit cojoin_square. HB.end. (* yoneda *) Section hom_repr. Context {C : cat} (F : C ~>_cat U). Definition homF : C -> U := fun c => hom c ~~> F. Section nat. Context (x y : C) (xy : x ~> y). (* Goal hom x ~~> F -> hom y ~~> F *) Context (n : hom x ~~> F). Definition homFhom c : hom y c ~> F c := fun g => n _ (xy \; g). Lemma homFhom_natural_subdef : IsNatural C U (hom y) F homFhom. Proof. by split=> a b f /=; apply/funext => g /=; rewrite /homFhom !Ucompx/= !naturalU/= Fcomp. Qed. HB.instance Definition _ := homFhom_natural_subdef. End nat. Arguments homFhom / : clear implicits. Check homFhom : forall x y : C, (x ~> y) -> (homF x -> homF y). HB.instance Definition _ := IsPreFunctor.Build _ _ homF homFhom. Lemma homF_functor_subproof : PreFunctor_IsFunctor _ _ homF. Proof. split=> [a|a b c f g]. apply/funext => -[/= f natf]. apply: natP => //=; apply: funext => b; apply: funext => g/=. by rewrite comp1o. apply/funext => -[/= h natf]. apply: natP => //=; apply: funext => d; apply: funext => k/=. by rewrite compoA. Qed. HB.instance Definition _ := homF_functor_subproof. Section pointed. Context (c : C). Definition hom_repr : homF c ~> F c := fun f => f _ idmap. Arguments hom_repr /. Definition repr_hom (fc : F c) a : hom c a ~> F a := fun f => F^$ f fc. Arguments repr_hom / : clear implicits. Lemma repr_hom_subdef (fc : F c) : IsNatural _ _ _ _ (repr_hom fc). Proof. by split=> a b f /=; apply/funext=> x; rewrite !Ucompx/= Fcomp. Qed. HB.instance Definition _ {fc : F c} := repr_hom_subdef fc. Definition repr_hom_nat : F c ~> homF c := repr_hom. Lemma hom_reprK : cancel hom_repr repr_hom_nat. Proof. move=> f; apply/natP; apply/funext => a; apply/funext => g /=. by rewrite -naturalU/=; congr (f _ _); apply: comp1o. Qed. Lemma repr_homK : cancel (repr_hom : F c ~> homF c) hom_repr. Proof. by move=> fc; rewrite /= F1. Qed. End pointed. Arguments hom_repr /. Arguments repr_hom /. Lemma hom_repr_natural_subproof : IsNatural _ _ _ _ hom_repr. Proof. split=> a b f /=; apply/funext => n /=; rewrite !Ucompx/= compo1/=. by rewrite -naturalU/=; congr (n _ _); apply/esym/comp1o. Qed. HB.instance Definition _ := hom_repr_natural_subproof. (* show this from the previous proof *) Lemma hom_natural_repr_subproof : IsNatural _ _ _ _ repr_hom_nat. Proof. split=> a b f /=; apply: funext => fa /=; rewrite !Ucompx/=. apply: natP; apply: funext => c /=; apply: funext => d /=. by rewrite Fcomp Ucompx/=. Qed. HB.instance Definition _ := hom_natural_repr_subproof. Definition hom_repr_nat : homF ~~> F := hom_repr. Definition repr_hom_nat_nat : F ~~> homF := repr_hom_nat. End hom_repr. (* comma categories *) Module comma. Section homcomma. Context {C D E : precat} (F : C ~> E) (G : D ~> E). Definition type := { x : C * D & F x.1 ~> G x.2 }. Definition hom_subdef (a b : type) := { f : tag a ~> tag b & F <$> f.1 \; tagged b = tagged a \; G <$> f.2 }. HB.instance Definition _ := IsQuiver.Build type hom_subdef. End homcomma. Arguments hom_subdef /. Section comma. Context {C D E : cat} (F : C ~> E) (G : D ~> E). Notation type := (type F G). Program Definition idmap_subdef (a : type) : a ~> a := @Tagged _ idmap _ _. Next Obligation. by move=> ? /=; rewrite /tagged/= !F1 comp1o compo1. Qed. Program Definition comp_subdef (a b c : type) (f : a ~> b) (g : b ~> c) : a ~> c := @Tagged _ (tag f \; tag g) _ _. Next Obligation. move=> a b c f g; rewrite /tagged/= !Fcomp -compoA /=. by rewrite (tagged g) compoA (tagged f) compoA. Qed. HB.instance Definition _ := IsPreCat.Build type idmap_subdef comp_subdef. Arguments idmap_subdef /. Arguments comp_subdef /. Lemma comma_homeqP (a b : type) (f g : a ~> b) : projT1 f = projT1 g -> f = g. Proof. case: f g => [f fP] [g +]/= eqfg; case: _ / eqfg => gP. by congr existT; apply: Prop_irrelevance. Qed. Lemma comma_is_cat : PreCat_IsCat type. Proof. by split=> [[a fa] [b fb] [*]|[a fa] [b fb] [*]|*]; apply/comma_homeqP; rewrite /= ?(comp1o, compo1, compoA). Qed. HB.instance Definition _ := comma_is_cat. End comma. End comma. Notation "F `/` G" := (@comma.type _ _ _ F G) (at level 40, G at level 40, format "F `/` G") : cat_scope. Notation "a /` G" := (cst unit a `/` G) (at level 40, G at level 40, format "a /` G") : cat_scope. Notation "F `/ b" := (F `/` cst unit b) (at level 40, b at level 40, format "F `/ b") : cat_scope. Notation "a / b" := (cst unit a `/ b) : cat_scope. Definition obj (C : quiver) : Type := C. HB.mixin Record IsInitial {C : quiver} (i : obj C) := { to : forall c, i ~> c; to_unique : forall c (f : i ~> c), f = to c }. #[short(type="initial")] HB.structure Definition Initial {C : quiver} := {i of IsInitial C i}. HB.mixin Record IsTerminal {C : quiver} (t : obj C) := { from : forall c, c ~> t; from_unique : forall c (f : c ~> t), f = from c }. #[short(type="terminal")] HB.structure Definition Terminal {C : quiver} := {t of IsTerminal C t}. HB.mixin Record IsMono {C : precat} (b c : C) (f : hom b c) := { monoP : forall (a : C) (g1 g2 : a ~> b), g1 \; f = g2 \; f -> g1 = g2 }. #[short(type="mono")] HB.structure Definition Mono {C : precat} (a b : C) := {m of IsMono C a b m}. Notation "a >~> b" := (mono a b) (at level 99, b at level 200, format "a >~> b") : cat_scope. Notation "C >~>_ T D" := (@mono T C D) (at level 99, T at level 0, only parsing) : cat_scope. HB.mixin Record IsEpi {C : precat} (a b : C) (f : hom a b) := { epiP : forall (c : C) (g1 g2 : b ~> c), g1 \o f = g2 \o f -> g1 = g2 }. #[short(type="epi")] HB.structure Definition Epi {C : precat} (a b : C) := {e of IsEpi C a b e}. Notation "a ~>> b" := (epi a b) (at level 99, b at level 200, format "a ~>> b") : cat_scope. Notation "C ~>>_ T D" := (@epi T C D) (at level 99, T at level 0, only parsing) : cat_scope. #[short(type="iso")] HB.structure Definition Iso {C : precat} (a b : C) := {i of @Mono C a b i & @Epi C a b i}. Notation "a <~> b" := (epi a b) (at level 99, b at level 200, format "a <~> b") : cat_scope. Notation "C <~>_ T D" := (@epi T C D) (at level 99, T at level 0, only parsing) : cat_scope. Definition comp1F {C D : cat} (F : C ~> D) : idmap \; F = F. Proof. by apply/functorP=> a b f; rewrite funext_frefl/= compFmap. Qed. Definition compF1 {C D : cat} (F : C ~> D) : F \; idmap = F. Proof. by apply/functorP=> a b f; rewrite funext_frefl/= compFmap. Qed. Definition feq {C : precat} {a b : C} : a = b -> a ~> b. Proof. by move<-; exact idmap. Defined. Definition feqsym {C : precat} {a b : C} : a = b -> b ~> a. Proof. by move<-; exact idmap. Defined. HB.mixin Record IsLeftAdjointOf (C D : cat) (R : D ~> C) L & @Functor C D L := { Lphi : forall c d, (L c ~> d) -> (c ~> R d); Lpsi : forall c d, (c ~> R d) -> (L c ~> d); (* there should be a monad and comonad structure wrappers instead *) Lunit : (idmap : C ~> C) ~> R \o (L : Functor.type C D); Lcounit : (L : Functor.type C D) \o R ~~> idmap :> D ~> D; LphiE : forall c d (g : L c ~> d), Lphi c d g = Lunit c \; (R <$> g); LpsiE : forall c d (f : c ~> R d), Lpsi c d f = (L <$> f) \; Lcounit d; Lwhiskerlr : let L : C ~> D := L : Functor.type C D in (feqsym (comp1F _) \; Lunit L) \; (L <$o> Lcounit \; feq (compF1 _)) = idmap; Lwhiskerrl : let L : C ~> D := L : Functor.type C D in (feqsym (compF1 _) \; R <$o> Lunit) \; (Lcounit R \; feq (comp1F _)) = idmap; }. #[short(type="left_adjoint_of")] HB.structure Definition LeftAdjointOf (C D : cat) (R : D ~> C) := { L of @Functor C D L & IsLeftAdjointOf C D R L}. Arguments Lphi {C D R s} {c d}. Arguments Lpsi {C D R s} {c d}. Arguments Lunit {C D R s}. Arguments Lcounit {C D R s}. (* Section LeftAdjointOf_Theory. *) (* Variables (C D : cat) (R : D ~> C) (L : LeftAdjointOf.type R). *) (* Lemma Lphi_psi (c : C) (d : D) : *) (* (@Lphi _ _ R L c d \o @Lpsi _ _ R L c d)%function = @id (c ~> R d). *) (* Proof. *) (* apply/funext => f /=; rewrite LphiE LpsiE. *) (* Admitted. *) (* Lemma Lpsi_phi (c : C) (d : D) : *) (* (@Lpsi _ _ R L c d \o @Lphi _ _ R L c d)%function = @id (L c ~> d). *) (* Proof. *) (* Admitted. *) (* End LeftAdjointOf_Theory. *) HB.mixin Record IsRightAdjoint (D C : cat) (R : D -> C) & @Functor D C R := { (* we should have a wrapper instead *) left_adjoint : C ~> D; LLphi : forall c d, (left_adjoint c ~> d) -> (c ~> R d); LLpsi : forall c d, (c ~> R d) -> (left_adjoint c ~> d); LLunit : (idmap : C ~> C) ~~> (R : Functor.type D C) \o left_adjoint; LLcounit : left_adjoint \o (R : Functor.type D C) ~~> idmap :> D ~> D; LLphiE : forall c d (g : left_adjoint c ~> d), LLphi c d g = LLunit c \; (R <$> g); LLpsiE : forall c d (f : c ~> R d), LLpsi c d f = (left_adjoint <$> f) \; LLcounit d; LLwhiskerlr : (feqsym (comp1F _) \; LLunit left_adjoint) \; (left_adjoint <$o> LLcounit \; feq (compF1 _)) = idmap; LLwhiskerrl : (feqsym (compF1 _) \; (R : Functor.type D C) <$o> LLunit) \; (LLcounit (R : Functor.type D C) \; feq (comp1F _)) = idmap; }. #[short(type="right_adjoint")] HB.structure Definition RightAdjoint (D C : cat) := { R of @Functor D C R & IsRightAdjoint D C R }. Arguments left_adjoint {_ _}. Arguments LLphi {D C s} {c d}. Arguments LLpsi {D C s} {c d}. Arguments LLunit {D C s}. Arguments LLcounit {D C s}. HB.mixin Record PreCat_IsMonoidal C & PreCat C := { onec : C; prod : (C * C)%type ~>_precat C; }. #[short(type="premonoidal")] HB.structure Definition PreMonoidal := { C of PreCat C & PreCat_IsMonoidal C }. Notation premonoidal := premonoidal. Arguments prod {C} : rename. Notation "a * b" := (prod (a, b)) : cat_scope. Reserved Notation "f <*> g" (at level 40, g at level 40, format "f <*> g"). Notation "f <*> g" := (prod^$ (f, g)) (only printing) : cat_scope. Notation "f <*> g" := (prod^$ ((f, g) : (_, _) ~> (_, _))) (only parsing) : cat_scope. Notation "1" := onec : cat_scope. Definition hom_cast {C : quiver} {a a' : C} (eqa : a = a') {b b' : C} (eqb : b = b') : (a ~> b) -> (a' ~> b'). Proof. now elim: _ / eqa; elim: _ / eqb. Defined. HB.mixin Record PreFunctor_IsMonoidal (C D : premonoidal) F & @PreFunctor C D F := { fun_one : F 1 = 1; fun_prod : forall (x y : C), F (x * y) = F x * F y; }. #[short(type="monoidal_prefunctor")] HB.structure Definition MonoidalPreFunctor C D := { F of @PreFunctor_IsMonoidal C D F }. Arguments fun_prod {C D F x y} : rename. (* Arguments fun_prodF {C D F x x'} f {y y'} g : rename. *) Unset Universe Checking. HB.instance Definition _ := IsQuiver.Build premonoidal MonoidalPreFunctor.type. Set Universe Checking. HB.instance Definition _ (C : quiver) := IsPreFunctor.Build (C * C)%type C fst (fun (a b : C * C) (f : a ~> b) => f.1). HB.instance Definition _ (C : quiver) := IsPreFunctor.Build (C * C)%type C snd (fun (a b : C * C) (f : a ~> b) => f.2). Definition prod3l {C : premonoidal} (x : C * C * C) : C := (x.1.1 * x.1.2) * x.2. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build _ C prod3l (fun a b (f : a ~> b) => (f.1.1 <*> f.1.2) <*> f.2). Definition prod3r {C : premonoidal} (x : C * C * C) : C := x.1.1 * (x.1.2 * x.2). HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build _ C prod3r (fun a b (f : a ~> b) => f.1.1 <*> (f.1.2 <*> f.2)). Definition prod1r {C : premonoidal} (x : C) : C := 1 * x. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build C C prod1r (fun (a b : C) (f : a ~> b) => \idmap_1 <*> f). Definition prod1l {C : premonoidal} (x : C) : C := x * 1. HB.instance Definition _ {C : premonoidal} := IsPreFunctor.Build C C prod1l (fun (a b : C) (f : a ~> b) => f <*> \idmap_1). HB.mixin Record PreMonoidal_IsMonoidal C & PreMonoidal C := { prodA : prod3l ~~> prod3r; prod1c : prod1r ~~> idfun; prodc1 : prod1l ~~> idfun; prodc1c : forall (x y : C), prodA (x, 1, y) \; \idmap_x <*> prod1c y = prodc1 x <*> \idmap_y; prodA4 : forall (w x y z : C), prodA (w * x, y, z) \; prodA (w, x, y * z) = prodA (w, x, y) <*> \idmap_z \; prodA (w, x * y, z) \; \idmap_w <*> prodA (x, y, z); }. Unset Universe Checking. #[short(type="monoidal")] HB.structure Definition Monoidal : Set := { C of PreMonoidal_IsMonoidal C & PreMonoidal C }. Set Universe Checking. HB.mixin Record IsRing A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[short(type="ring")] HB.structure Definition Ring := { A of IsRing A }. Bind Scope algebra_scope with Ring.sort. Notation "0" := zero : algebra_scope. Notation "1" := one : algebra_scope. Infix "+" := (@add _) : algebra_scope. Notation "- x" := (@opp _ x) : algebra_scope. Infix "*" := (@mul _) : algebra_scope. Notation "x - y" := (x + - y) : algebra_scope. Lemma addr0 (R : ring) : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN (R : ring) : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma addKr (R : ring) (x : R) : cancel (add x) (add (- x)). Proof. by move=> y; rewrite addrA addNr add0r. Qed. Lemma addrI (R : ring) (x : R) : injective (add x). Proof. exact: can_inj (addKr _). Qed. Lemma opprK (R : ring) : involutive (@opp R). Proof. by move=> x; apply: (@addrI _ (- x)); rewrite addNr addrN. Qed. HB.mixin Record IsRingHom (A B : ring) (f : A -> B) := { hom1_subproof : f 1%A = 1%A; homB_subproof : {morph f : x y / x - y}; homM_subproof : {morph f : x y / (x * y)%A}; }. HB.structure Definition RingHom A B := { f of IsRingHom A B f }. Lemma id_IsRingHom A : IsRingHom A A idfun. Proof. by []. Defined. HB.instance Definition _ A := id_IsRingHom A. Lemma comp_IsRingHom (A B C : ring) (f : RingHom.type A B) (g : RingHom.type B C) : IsRingHom A C (g \o f)%function. Proof. by constructor => [|x y|x y]; rewrite /comp/= ?hom1_subproof ?homB_subproof ?homM_subproof. Qed. HB.instance Definition _ A B C f g := @comp_IsRingHom A B C f g. HB.instance Definition _ := IsQuiver.Build ring RingHom.type. HB.instance Definition _ := Quiver_IsPreCat.Build ring (fun a => @idfun a : RingHom.type a a) (fun a b c (f : a ~> b) (g : b ~> c) => (g \o f)%function : RingHom.type _ _). HB.instance Definition _ := Quiver_IsPreConcrete.Build ring (fun _ _ => id). Lemma ring_precat : PreConcrete_IsConcrete ring. Proof. constructor => A B [f cf] [g cg]//=; rewrite -[_ = _]/(f = g) => fg. case: _ / fg in cg *; congr {|RingHom.sort := _ ; RingHom.class := _|}. case: cf cg => [[? ? ?]] [[? ? ?]]. by congr RingHom.Class; congr IsRingHom.phant_Build => //=; apply: Prop_irrelevance. Qed. HB.instance Definition _ := ring_precat. Lemma ring_IsCat : PreCat_IsCat ring. Proof. by constructor=> [A B f|A B f|A B C D f g h]; exact: concrete_fun_inj. Qed. HB.instance Definition _ := ring_IsCat. Lemma hom1 (R S : ring) (f : R ~> S) : f 1%A = 1%A. Proof. exact: hom1_subproof. Qed. Lemma homB (R S : ring) (f : R ~> S) : {morph f : x y / x - y}. Proof. exact: homB_subproof. Qed. Lemma homM (R S : ring) (f : R ~> S) : {morph f : x y / (x * y)%A}. Proof. exact: homM_subproof. Qed. Lemma hom0 (R S : ring) (f : R ~> S) : f 0%A = 0%A. Proof. by rewrite -(addrN 1%A) homB addrN. Qed. Lemma homN (R S : ring) (f : R ~> S) : {morph f : x / - x}. Proof. by move=> x; rewrite -[- x]add0r homB hom0 add0r. Qed. Lemma homD (R S : ring) (f : R ~> S) : {morph f : x y / x + y}. Proof. by move=> x y; rewrite -[y]opprK !homB !homN. Qed. HB.mixin Record IsIdeal (R : ring) (I : R -> Prop) := { ideal0 : I 0; idealD : forall x y, I x -> I y -> I (x + y); idealM : forall x y, I y -> I (x * y)%A; }. HB.structure Definition Ideal (R : ring) := { I of IsIdeal R I }. HB.mixin Record Ideal_IsPrime (R : ring) (I : R -> Prop) & IsIdeal R I := { ideal_prime : forall x y : R, I (x * y)%A -> I x \/ I y }. #[short(type="spectrum")] HB.structure Definition PrimeIdeal (R : ring) := { I of Ideal_IsPrime R I & Ideal R I }. math-comp-hierarchy-builder-4d8a939/examples/demo3/000077500000000000000000000000001521677141400222035ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_0.v000066400000000000000000000013341521677141400245700ustar00rootroot00000000000000From HB Require Import structures. From Corelib Require Import ssreflect ssrfun. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of MulMonoid A & Ring_of_MulMonoid A }. math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_1.v000066400000000000000000000030151521677141400245670ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record AddMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_Type A }. HB.mixin Record Ring_of_AddMulMonoid A & MulMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.structure Definition Ring := { A of MulMonoid A & AddMonoid A & Ring_of_AddMulMonoid A }. HB.factory Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_MulMonoid A). HB.instance Definition to_AddMonoid_of_Type := AddMonoid_of_Type.Build A zero add addrA add0r addr0. HB.instance Definition to_Ring_of_AddMulMonoid := Ring_of_AddMulMonoid.Build A opp addrC addNr mulrDl mulrDr. HB.end. math-comp-hierarchy-builder-4d8a939/examples/demo3/hierarchy_2.v000066400000000000000000000044731521677141400246010ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record MulMonoid_of_Type A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; }. HB.structure Definition MulMonoid := { A of MulMonoid_of_Type A }. HB.mixin Record AddMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_Type A }. HB.mixin Record AbGroup_of_AddMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbGroup := { A of AddMonoid A & AbGroup_of_AddMonoid A }. HB.mixin Record Ring_of_AbGroupMulMonoid A & MulMonoid A & AbGroup A := { mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.structure Definition Ring := { A of MulMonoid A & AbGroup A & Ring_of_AbGroupMulMonoid A }. HB.factory Record Ring_of_AddMulMonoid A & MulMonoid A & AddMonoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul (add : A -> A -> A); mulrDr : right_distributive mul (add : A -> A -> A); }. HB.builders Context A (a : Ring_of_AddMulMonoid A). HB.instance Definition to_AbGroup_of_AddMonoid := AbGroup_of_AddMonoid.Build A opp addrC addNr. HB.instance Definition to_Ring_of_AbGroupMulMonoid := Ring_of_AbGroupMulMonoid.Build A mulrDl mulrDr. HB.end. HB.factory Record Ring_of_MulMonoid A & MulMonoid A := { zero : A; add : A -> A -> A; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_MulMonoid A). HB.instance Definition to_AddMonoid_of_Type := AddMonoid_of_Type.Build A zero add addrA add0r addr0. HB.instance Definition to_AbGroup_of_AddMonoid := AbGroup_of_AddMonoid.Build A opp addrC addNr. HB.instance Definition to_Ring_of_AddMulMonoid := Ring_of_AddMulMonoid.Build A opp addrC addNr mulrDl mulrDr. HB.end. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_0_0.v000066400000000000000000000035031521677141400240100ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_0. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_1_0.v000066400000000000000000000035031521677141400240110ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_1. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/test_2_0.v000066400000000000000000000035031521677141400240120ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From Corelib Require Import BinNums IntDef. From HB Require Import structures. From HB Require Import demo3.hierarchy_2. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z (Zpos xH) Z.mul Z_mul_assoc Z_mul_1_l Z_mul_1_r. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). HB.instance Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z Z0 Z.add Z_add_assoc Z_add_0_l Z_add_0_r Z.opp Z_add_comm Z_add_opp_diag_l Z_mul_add_distr_r Z_mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples/demo3/user_0.v000066400000000000000000000022661521677141400235750ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect ssrfun. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. (* Instance *) Definition Z_mulmonoid_axioms := MulMonoid_of_Type.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r. HB.instance Z Z_mulmonoid_axioms. Definition Z_ring_axioms := Ring_of_MulMonoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r Z.opp Z.add_comm Z.add_opp_diag_l Z.mul_add_distr_r Z.mul_add_distr_l. HB.instance Z Z_ring_axioms.math-comp-hierarchy-builder-4d8a939/examples/demo4/000077500000000000000000000000001521677141400222045ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo4/hierarchy_0.v000066400000000000000000000013271521677141400245730ustar00rootroot00000000000000From HB Require Import structures. #[key="A"] HB.mixin Record m1 (T : Type) (A : Type) := { inhab : A; inhab_param : T; }. HB.structure Definition s1 T := { A of m1 T A }. Check inhab. (* inhab : forall (T : Type) (A : s1.type T), s1.sort A *) HB.instance Definition nat_m1 := m1.Build bool nat 7 false. Check (refl_equal _ : @inhab _ _ = 7). HB.instance Definition list_m1 A := m1.Build (option A) (list nat) (cons 7 nil) None. Check (refl_equal _ : @inhab _ _ = (cons 7 nil)). HB.mixin Record m2 (T : Type) (A : Type) & m1 T A := { inj : T -> A; }. HB.structure Definition s2 T := { A of m1 T A & m2 T A }. Check fun X : s2.type nat => inhab : X. Check fun X : s2.type nat => inj : nat -> X. About s2_to_s1. math-comp-hierarchy-builder-4d8a939/examples/demo5/000077500000000000000000000000001521677141400222055ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples/demo5/hierarchy_0.v000066400000000000000000000117241521677141400245760ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* Begin change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.mixin Record LModule_of_AG (R : Ring.type) (M : Type) & AddAG M := { scale : Ring.sort R -> M -> M; (* TODO: insert coercions automatically *) scaleDl : forall v, {morph scale^~ v: a b / a + b}; scaleDr : right_distributive scale add; scaleA : forall a b v, scale a (scale b v) = scale (a * b) v; scale1r : forall m, scale 1 m = m; }. HB.structure Definition LModule (R : Ring.type) := { M of LModule_of_AG R M & }. Infix "*:" := (@scale _ _) (at level 30) : hb_scope. Definition regular (R : Type) := R. HB.instance Definition regular_AG (R : AddAG.type) := AddAG_of_TYPE.Build (regular (AddAG.sort R)) zero add opp addrA addrC add0r addNr. HB.instance Definition regular_LModule (R : Ring.type) := LModule_of_AG.Build R (regular (Ring.sort R)) mul (fun _ _ _ => mulrDl _ _ _) mulrDr mulrA mul1r. From Corelib Require Import BinNums IntDef. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_0_r : forall x, Z.add x Z0 = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. Axiom Z_mul_add_distr_l : forall x y z, Z.mul x (Z.add y z) = Z.add (Z.mul x y) (Z.mul x z). Axiom Z_mul_add_distr_r : forall x y z, Z.mul (Z.add x y) z = Z.add (Z.mul x z) (Z.mul y z). Axiom Z_mul_assoc : forall x y z, Z.mul x (Z.mul y z) = Z.mul (Z.mul x y) z. Axiom Z_mul_1_l : forall x, Z.mul (Zpos xH) x = x. Axiom Z_mul_1_r : forall x, Z.mul x (Zpos xH) = x. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z Z0 (Zpos xH) Z.add Z.opp Z.mul Z_add_assoc Z_add_comm Z_add_0_l Z_add_opp_diag_l Z_mul_assoc Z_mul_1_l Z_mul_1_r Z_mul_add_distr_r Z_mul_add_distr_l. Lemma test (m : Z) (n : regular Z) : m *: n = m * n. Proof. by []. Qed. math-comp-hierarchy-builder-4d8a939/examples/hulk.v000066400000000000000000000245141521677141400223340ustar00rootroot00000000000000 From HB Require Import structures. Require Import ssreflect ssrfun ssrbool. (* ******************************************************************* *) (* *********************** Hierarchy design ************************** *) (* ******************************************************************* *) Module BadInheritance. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T := { sq : T -> T; }. HB.structure Definition Sq := { T of HasSq T }. (* We need a functorial construction (a container) which preserves both structures. The simplest one is the option type. *) Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square. (* Now we mix the two unrelated structures by building Sq out of Mul. *** This breaks Non Forgetful Inheritance *** https://math-comp.github.io/competing-inheritance-paths-in-dependent-type-theory/ *) #[non_forgetful_inheritance] HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As we expect we can proved this (by reflexivity) *) Lemma sq_mul (V : Mul.type) (v : V) : sq v = mul v v. Proof. by reflexivity. Qed. Lemma problem (W : Mul.type) (w : option W) : sq w = mul w w. Proof. Fail reflexivity. (* What? It used to work! *) Fail rewrite sq_mul. (* Lemmas don't cross the container either! *) (* Let's investigate *) rewrite /mul/= /sq/=. (* As we expect, we are on the option type. In the LHS it is the Sq built using the NFI instance option_square w = option_mul w w *) rewrite /option_mul/=. rewrite /option_square/sq/=. congr (match w with Some n => _ | None => None end). (* The branches for Some differ, since w is a variable, they don't compare as equal (fun n : W => Some (mul n n)) = (fun n : W => match w with | Some m => Some (mul n m) | None => None end) *) Abort. End BadInheritance. Module GoodInheritance. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T & Mul T := { sq : T -> T; sq_mul : forall x, sq x = mul x x; }. HB.structure Definition Sq := { T of HasSq T & Mul T }. Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. Lemma option_sq_mul {T : Sq.type} (o : option T) : option_square o = mul o o. Proof. by rewrite /option_square; case: o => [x|//]; rewrite sq_mul. Qed. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square option_sq_mul. Lemma problem (W : Sq.type) (w : option W) : sq w = mul w w. Proof. by rewrite sq_mul. Qed. End GoodInheritance. (* ******************************************************************* *) (* ********************** Feather factories *********************** *) (* ******************************************************************* *) (* HB comes with a concept of factory, a virtual interface that is compiled down to the real ones. When the contents of a factory are just one lemma, the following trick may come handy. We define a type "link" which is convertible to a new type T but carries, as a dummy argument, a proof that T is linked to some known type xT. We can then use "link" to transfer (copy) structure instances across the link. *) Module Feather. (* We need a hierarchy with a few structure, here we Equality -> Singleton *) HB.mixin Record HasEqDec T := { eqtest : T -> T -> bool; eqOK : forall x y, reflect (x = y) (eqtest x y); }. HB.structure Definition Equality := { T of HasEqDec T }. HB.mixin Record IsContractible T & HasEqDec T := { def : T; all_def : forall x, eqtest x def = true; }. HB.structure Definition Singleton := { T of IsContractible T }. (* This is the type which is used as a feather factory. - xT plays the role of a rich type, - T is a new type linked to xT by some lemma. In this case a very strong cancellation lemma canfg *) Definition link {xT T : Type} {f : xT -> T} {g : T -> xT} (canfg : forall x, f (g x) = x) := T. (* (link canfg) is convertible to T *) (* We explain HB how to transfer Equality over link *) Section TransferEQ. Context {eT : Equality.type} {T : Type} {f : eT -> T} {g : T -> eT}. Context (canfg : forall x, f (g x) = x). Definition link_eqtest (x y : T) : bool := eqtest (g x) (g y). Lemma link_eqOK (x y : T) : reflect (x = y) (link_eqtest x y). Proof. rewrite /link_eqtest; case: (eqOK (g x) (g y)) => [E|abs]. by constructor; rewrite -[x]canfg -[y]canfg E canfg. by constructor=> /(f_equal g)/abs. Qed. (* (link canfg) is now an Equality instance *) HB.instance Definition link_HasEqDec := HasEqDec.Build (link canfg) link_eqtest link_eqOK. End TransferEQ. (* We explain HB how to transfer Singleton over link *) Section TransferSingleton. Context {eT : Singleton.type} {T : Type} {f : eT -> T} {g : T -> eT}. Context (canfg : forall x, f (g x) = x). Definition link_def : link canfg := f def. Lemma link_all_def x : eqtest x link_def = true. Proof. rewrite /link_def; have /eqOK <- := all_def (g x). by rewrite canfg; case: (eqOK x x). Qed. (* (link canfg) is now a Signleton instance *) HB.instance Definition _ := IsContractible.Build (link canfg) link_def link_all_def. End TransferSingleton. (* We assume a known type B which is both an Equality and a Singleton *) Axiom B : Type. Axiom testB : B -> B -> bool. Axiom testOKB : forall x y, reflect (x = y) (testB x y). HB.instance Definition _ := HasEqDec.Build B testB testOKB. Axiom defB : B. Axiom all_defB : forall x, eqtest x defB = true. HB.instance Definition _ := IsContractible.Build B defB all_defB. (* Now we copy all instances from B to A via link *) Axiom A : Type. Axiom f : B -> A. Axiom g : A -> B. Axiom canfg : forall x, f (g x) = x. (* We take all the instances up to Singleton on (link canfg) and we copy them on A. Recall (link canfg) is convertible to A *) HB.instance Definition _ := Singleton.copy A (link canfg). HB.about A. (* both Equality and Singleton have been copied *) End Feather. (* ******************************************************************* *) (* ********************** Abstraction barriers *********************** *) (* ******************************************************************* *) Notation "n ^ m" := (Nat.pow n m) : nat_scope. Module SlowFailure. (* When building a library it is natural to stack definitions up and reuse things you already have as much as possible. More often that not we want to set up abstraction barriers. For example one may define a mathematical concept using, say, lists and their operations, provide a few lemmas about the new concept, and then expect the user to never unfold the concept and work with lists directly. Abstraction barriers are not only good for clients, which are granted to work at the right abstraction level, but also for Coq itself, since it may be tricked into unfolding definitions and manipulate huge terms. HB.lock is a tool to easily impose abstraction barriers. It uses modules and module signatures to seal the body of a definition, keeping access to it via an equation. *) (* not a very clever construction, but a large one. Bare with us. *) Definition new_concept := 999999. Lemma test x : new_concept ^ x ^ new_concept = x ^ new_concept ^ new_concept. Proof. (* this goal is not trivial, and maybe even false, but you may call some automation on it anyway *) Time Fail reflexivity. (* takes 7s, note that both by and // call reflexivity *) Abort. End SlowFailure. Module FastFailure. HB.lock Definition new_concept := 999999. Lemma test x : new_concept ^ x ^ new_concept = x ^ new_concept ^ new_concept. Time Fail reflexivity. (* takes 0s *) rewrite new_concept.unlock. Time Fail reflexivity. (* takes 7s, the original body is restored *) Abort. Print Module Type new_concept_Locked. Print Module new_concept. (* Module Type new_conceptLocked = Sig Parameter body : nat. Parameter unlock : body = 999999 End Module new_concept : new_conceptLocked := ... *) Print new_concept. (* Notation new_concept := new_concept.body *) Canonical unlock_new_concept := Unlockable new_concept.unlock. End FastFailure. (* ******************************************************************* *) (* ******************************* Joins ***************************** *) (* ******************************************************************* *) (* All structures which are not leaves must be joinable *) Module MissingJoin. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. Fail HB.structure Definition A2B1 := {M of A2 M & B1 M }. HB.graph "missing_join.dot". End MissingJoin. Module GoodJoin. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition join := {M of A1 M & A2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. HB.structure Definition A2B1 := {M of A2 M & B1 M }. HB.graph "good_join.dot". End GoodJoin. math-comp-hierarchy-builder-4d8a939/examples/readme.v000066400000000000000000000030551521677141400226230ustar00rootroot00000000000000From HB Require Import structures. From Corelib Require Import ssreflect BinNums IntDef. #[verbose, log] HB.mixin Record AddComoid_of_Type A := { zero : A; add : A -> A -> A; addrA : forall x y z, add x (add y z) = add (add x y) z; addrC : forall x y, add x y = add y x; add0r : forall x, add zero x = x; }. #[verbose, log(raw)] HB.structure Definition AddComoid := { A of AddComoid_of_Type A }. Notation "0" := zero. Infix "+" := add. Check forall (M : AddComoid.type) (x : M), x + x = 0. HB.mixin Record AbelianGrp_of_AddComoid A & AddComoid_of_Type A := { opp : A -> A; addNr : forall x, opp x + x = 0; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_AddComoid A & }. Notation "- x" := (opp x). Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0. Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed. Axiom Z_add_assoc : forall x y z, Z.add x (Z.add y z) = Z.add (Z.add x y) z. Axiom Z_add_comm : forall x y, Z.add x y = Z.add y x. Axiom Z_add_0_l : forall x, Z.add Z0 x = x. Axiom Z_add_opp_diag_l : forall x, Z.add (Z.opp x) x = Z0. HB.instance Definition Z_CoMoid := AddComoid_of_Type.Build Z Z0 Z.add Z_add_assoc Z_add_comm Z_add_0_l. HB.instance Definition Z_AbGrp := AbelianGrp_of_AddComoid.Build Z Z.opp Z_add_opp_diag_l. Lemma example2 (x : Z) : x + (- x) = - 0. Proof. by rewrite example. Qed. Check AbelianGrp.on Z. HB.graph "readme.dot". HB.about Z. Section Test. HB.declare Context (T : Type) (p : AddComoid_of_Type T) (q : AbelianGrp_of_AddComoid T). Goal forall x : T, x + -x = 0. Abort. End Test. math-comp-hierarchy-builder-4d8a939/examples_stdlib/000077500000000000000000000000001521677141400225355ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/000077500000000000000000000000001521677141400254415ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_abstract.v000066400000000000000000000054131521677141400305120ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. HB.mixin Record CMonoid_of_Type A := { (* The set of axioms making A a commutative monoid. *) zero : A; add : A -> A -> A; addrA : associative add; (* `add` is associative *) addrC : commutative add; (* `add` is commutative *) add0r : left_id zero add; (* `zero` is a neutral element *) }. HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. (* The structure thereof. *) Notation "0" := zero. Infix "+" := add. (* The type of the operations and axioms depend on a CMonoid.type structure. *) Check addrC. (* ?M : CMonoid.type |- commutative (@add ?M) *) HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; (* We can write `add` here since A is a CMonoid *) addNr : left_inverse zero opp add; (* `opp` is the additive inverse *) }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A }. Notation "- x" := (opp x). Notation "x - y" := (add x (opp y)). HB.mixin Record SemiRing_of_CMonoid A & CMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; (* `mul` is associative *) mul1r : left_id one mul; (* `one` is left neutral *) mulr1 : right_id one mul; (* `one` is right neutral *) mulrDl : left_distributive mul add; (* `mul` distributes over *) mulrDr : right_distributive mul add; (* `add` on both sides *) mul0r : left_zero zero mul; (* `zero` is absorbing `mul` *) mulr0 : right_zero zero mul; (* on both sides *) }. HB.structure Definition SemiRing := { A of SemiRing_of_CMonoid A }. Notation "1" := one. Infix "*" := mul. (* We need no additional mixin to declare the Ring structure. *) HB.structure Definition Ring := { A of SemiRing_of_CMonoid A & AbelianGrp_of_CMonoid A }. (* An example statement in the signature of an Abelian group G, combining 0 and -. *) Check forall G : AbelianGrp.type, forall x : G, x - x = 0. (* An example statement in the signature of a Semiring S, combining 0, +, and *. *) Check forall S : SemiRing.type, forall x : S, x * 1 + 0 = x. (* An example statement in the signature of a Ring R, combining -, 1 and *. *) Check forall R : Ring.type, forall x y : R, x * - (1 * y) = - x * y. HB.instance Definition Z_CMonoid := CMonoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbelianGrp := AbelianGrp_of_CMonoid.Build Z Z.opp Z.add_opp_diag_l. HB.instance Definition Z_SemiRing := SemiRing_of_CMonoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. (* An example statement in the signature of the Z ring, combining Z, 0, +, -, 1 and * *) Check forall x : Z, x * - (1 + x) = 0 + 1. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_demo.v000066400000000000000000000145441521677141400276400ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". (* ****************************************************** *) (* ******** 1. Building the hierarchy ********** *) (* ****************************************************** *) (* ******************************************************** The set of axioms that turn a naked type A into a Commutative Monoid. This would be the puzzle piece. *) HB.mixin (* an HB command *) Record CMonoid_of_Type A := { (* and its argument *) zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. (* ******************************************************** The structure of Commutative Monoids This would be the blue dotted box Note: { A of ... } is just a notation for a sigma type *) HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. (* ******************************************************** Monoid playground *) (* Operations are now available *) Check add. (* Axioms are also there *) Check addrC. (* We can develop the abstract theory of CMonoid *) Notation "0" := zero. Infix "+" := add. Lemma silly : forall (M : CMonoid.type) (x : M), x + 0 = 0 + x. Proof. by move=> M x; rewrite addrC. Qed. (* ******************************************************** The puzzle piece on the right and the AbelianGrp str. Note: it requires A to be a monoid, indeed the property talk about both add and opp *) HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A }. Notation "- x" := (opp x). Notation "x - y" := (add x (opp y)). (* Quick check that - and + and 0 are compatible *) Check forall x y, x - (y + 0) = x. (* ******************************************************** The puzzle piece on the left and the SemiRing str. *) HB.mixin Record SemiRing_of_CMonoid A & CMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of SemiRing_of_CMonoid A & }. Notation "1" := one. Infix "*" := mul. (* Quick check that + and 1 and * are compatible *) Check forall x y, 1 + x = y * x. (* ******************************************************** Can I mix * and - in the same expression? *) Fail Check forall x y, 1 * x = y - x. (* ******************************************************** The missing structure, no puzzle piece is missing *) HB.structure Definition Ring := { A of SemiRing A & AbelianGrp A }. Check forall (R : Ring.type) (x y : R), 1 * x = y - x. Check forall x y, 1 * x = y - x. (* ****************************************************** *) (* ******** 2. Declaring instances ******** *) (* ****************************************************** *) (* ****************************************************** Inhabiting the puzzle pieces with Z *) Module Z_instances. HB.instance Definition Z_CMonoid := CMonoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_AbelianGrp := AbelianGrp_of_CMonoid.Build Z Z.opp Z.add_opp_diag_l. HB.instance Definition Z_SemiRing := SemiRing_of_CMonoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. (* Now Z is recognized as a Ring *) Check forall x : Z, x * - (1 + x) = 0 + 1. End Z_instances. (* ****************************************************** *) (* ********** 3. Being nice with users ******** *) (* ****************************************************** *) (* ******************************************************** Crafting special builders We provide an API to build a ring directly. A factory is a ''virtual'' puzzle piece that can be ''compiled'' to other puzzle pieces. *) HB.factory Record Ring_of_Type A := { zero : A; add : A -> A -> A; opp : A -> A; one : A; mul : A -> A -> A; addrA : associative add; (*addrC : commutative add; *) add0r : left_id zero add; addr0 : right_id zero add; (* new *) addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; (* new *) mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. (* The ''compilation'' of a factory *) HB.builders Context A & Ring_of_Type A. (* We are in a Context with a type A that with operations and properties, but which is not yet known to be a Ring *) Check add. Local Infix "+" := add. (* We prove commutativity as per Hankel 1867 *) Lemma addrC : commutative add. Proof. have innerC (a b : A) : a + b + (a + b) = a + a + (b + b). by rewrite -[a + b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : A) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : A) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. HB.instance Definition A_CMonoid := CMonoid_of_Type.Build A zero add addrA addrC add0r. HB.instance Definition A_AbelianGrp := AbelianGrp_of_CMonoid.Build A opp addNr. HB.instance Definition A_SemiRing := SemiRing_of_CMonoid.Build A one mul mulrA mul1r mulr1 mulrDl mulrDr mul0r mulr0. HB.end. (* Let's use the new builder *) Module Z_instances_again. HB.instance Definition Z_Ring := Ring_of_Type.Build Z 0%Z Z.add Z.opp 1%Z Z.mul Z.add_assoc (* Z.add_comm *) Z.add_0_l Z.add_0_r Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Check forall x : Z, x * - (1 + x) = 0 + 1. End Z_instances_again. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/000077500000000000000000000000001521677141400305215ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/withHB.v000066400000000000000000000011671521677141400321020ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". HB.mixin Record CMonoid_of_Type A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition CMonoid := { A of CMonoid_of_Type A }. HB.mixin Record AbelianGrp_of_CMonoid A & CMonoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGrp := { A of AbelianGrp_of_CMonoid A & }. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/CoqWS_expansion/withoutHB.v000066400000000000000000000076531521677141400326400ustar00rootroot00000000000000(* Accompanying material to Coq workshop presentation *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Set Warnings "-redundant-canonical-projection". (* Helpers *) Notation "[unify t1 'with' t2 ]" := (unify _ _ t1 t2 _) (at level 0, format "[unify t1 'with' t2 ]", only printing). Notation "[unify t1 'with' t2 ]" := (unify _ _ t1 t2 NoMsg) (at level 0, format "[unify t1 'with' t2 ]", only parsing). Module CMonoid_of_Type. Section CMonoid_of_Type. Variable (A : Type). Record axioms_ : Type := Axioms_ { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add }. Definition phant_Build (zero : A) (add : A -> A -> A) (addrA : associative add) (addrC : commutative add) := [eta CMonoid_of_Type.Axioms_ zero add addrA addrC]. Definition phant_axioms := CMonoid_of_Type.axioms_. End CMonoid_of_Type. Notation Build A := (phant_Build A). Notation axioms A := (phant_axioms A). Module Exports. Notation CMonoid_of_Type A := (axioms A). End Exports. End CMonoid_of_Type. Export CMonoid_of_Type.Exports. Module CMonoid. Record axioms (A : Type) : Type := Class { CMonoid_of_Type_mixin : CMonoid_of_Type.axioms_ A }. Record type : Type := Pack { sort : Type; class : axioms sort }. Module Exports. Coercion sort : type >-> Sortclass. Definition zero {s : type} := CMonoid_of_Type.zero _ (CMonoid_of_Type_mixin _ (class s)). Definition add {s : type} (x y : s) : s := CMonoid_of_Type.add _ (CMonoid_of_Type_mixin _ (class s)) x y. Definition addrA {s : type} : associative add := CMonoid_of_Type.addrA _ (CMonoid_of_Type_mixin _ (class s)). Definition addrC {s : type} : commutative add := CMonoid_of_Type.addrC _ (CMonoid_of_Type_mixin _ (class s)). Definition add0r {s : type} : left_id zero add := CMonoid_of_Type.add0r _ (CMonoid_of_Type_mixin _ (class s)). End Exports. End CMonoid. Export CMonoid.Exports. Module AbelianGrp_of_CMonoid. Section AbelianGrp_of_CMonoid. Variable (A : Type). Notation M m := (CMonoid.Pack A (CMonoid.Class A m)). Record axioms_ (m : CMonoid_of_Type.axioms_ A) := Axioms_ { opp : A -> A; addNr : left_inverse (@zero (M m)) opp (@add (M m)) }. Definition phant_Build := fun (s : CMonoid.type) & [unify A with CMonoid.sort s] => fun (c : CMonoid.axioms A) & [unify s with CMonoid.Pack A c] => fun (m : CMonoid_of_Type.axioms_ A) & [unify c with CMonoid.Class A m] => fun (opp : A -> A) (addNr : left_inverse (@zero (M m)) opp (@add (M m))) => Axioms_ m opp addNr. Definition phant_axioms := fun (s : CMonoid.type) & [unify A with CMonoid.sort s] => fun (c : CMonoid.axioms A) & [unify s with CMonoid.Pack A c] => fun (m : CMonoid_of_Type.axioms_ A) & [unify c with CMonoid.Class A m] => axioms_ m. End AbelianGrp_of_CMonoid. Notation Build A := (phant_Build A _ id_phant _ id_phant _ id_phant). Notation axioms A := (phant_axioms A _ id_phant _ id_phant _ id_phant). Module Exports. Notation AbelianGrp_of_CMonoid A := (axioms A). End Exports. End AbelianGrp_of_CMonoid. Export AbelianGrp_of_CMonoid.Exports. Module AbelianGrp. Record axioms (A : Type) : Type := Class { CMonoid_of_Type_mixin : CMonoid_of_Type.axioms_ A; AbelianGrp_of_CMonoid_mixin : AbelianGrp_of_CMonoid.axioms_ A CMonoid_of_Type_mixin }. Record type : Type := Pack { sort : Type; class : axioms sort }. Module Exports. Coercion sort : type >-> Sortclass. Coercion AbelianGrp_class_to_CMonoid_class (A : Type) (c : axioms A) := CMonoid.Class A (CMonoid_of_Type_mixin A c). Coercion AbelianGrp_to_CMonoid (A : AbelianGrp.type) := CMonoid.Pack A (class A). Canonical AbelianGrp_to_CMonoid. Definition opp {s : type} (x : s) : s := AbelianGrp_of_CMonoid.opp _ _ (AbelianGrp_of_CMonoid_mixin _ (class s)) x. Definition addNr {s : type} : left_inverse (@zero s) opp (@add s) := AbelianGrp_of_CMonoid.addNr _ _ (AbelianGrp_of_CMonoid_mixin _ (class s)). End Exports. End AbelianGrp. Export AbelianGrp.Exports. math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/diagram.pdf000066400000000000000000001200731521677141400275430ustar00rootroot00000000000000%PDF-1.5 % 4 0 obj << /Length 5 0 R /Filter /FlateDecode >> stream xͮ%=%6c8' x`{8vZ{*у[YcAKp 1PǑtc]*X_sjm k|ԭDF)PDr>T݀(HYpɾo$¸>uNA!$ Lm"ŧoq& tσ*&[$AR˔Nɐ[^M ]eIe3{/.νՋYگA+~Ĵb@nbHww^|R,z`ʱ9s>aReLƙ"s:6Z7F] rSqэERȕV{)2x'Q=jj96~e~!_2M濯 7* #qb7"o㰈<5?}qꏤGb:>TD6}^C`8,nE7l$\j~C<5֘$2;g#uԚAb>T~XCe:Y qRԶc  {E^zl0Ńs܇.>($剨f~~¡yi.m)?p/N!cC22Jڰs1?bGj{y !  YC`Ё _z2?f,8#pPcoiN~FG-84gMXjz.g/b(z8C^LqM8T~~Gߏ+5r6<~A㠔pCE<`!bgOq_5q|:A`qo!ZcM{VQ )1f3?QzL8KIastkZq|vBUרu@ iGϿ؂w_|3%"0]~]ۯ:lExw< R_cVii> ^\oqAyh濅om^zğ韛uL'u5o6jc97@-e!;w\̫O ~g&˓jL^iY$&ω[{UX?78v >bNJo{(ٖ^6Z}trR_m%0FeF fI2T F4Ws?j"}<k<i K3)~.8 QwgA_m}2j'xE噋 ݤbKA>.+~G\W*tT? G1dRLm]hvہ nMB8[0kώrl!sJ'bh }kP7{sWv f sXx]_Lqk[]lnt -mT C o`<7"e1N/z:fÉvk~y:ܾ=Qkk^)\HD ~]_U:q~]#?>WeMΪ q!!CnT7mGpϴR?3t\]OCd 0!6Ƥn3& .x́+f/8*l SyǣɒY@-n@\Ϧ 6xep^XӾ7ܜ \yxȐ-1%Yo׶??Wܺ?iՆqDx,W|AF7WV[vsuGvE/z(!ؑTն 3!f;7 .06ϥ+;pȿG+}~8ۼϣX4]p gKɿa&n57c*l`!^ دZCbQQ6_Oe~wž!iSc5eYzcI )5t"Qvar|OHkD9c_Ͻ .*+}OG̼(:gl!; +iS%Ox@IC:=Oy5o0\c@TnV/*L9зߘ01{VO3bT}"9Z( \ⰅR柤Z摭8M un8ڐa\OjWºvql#JsNOa)aO\Vڄ_ڞǯ/0kA9x.&kX yZKV5;~{d(?:!H,3*`.z=AfW 0"8C]8Q|=ʐ\ l]"!ɏ Q}2OCҢ@rrzGi?>PaÇa~mLfAW]chTG]nxOء+u#Bt: &3%א8+K!γ?d^1h\+z햰~bqlC2@̏2~0Q~bxgeE\W#[|S|~zSf)'5jv5> ?w/e)_-i{ցVֶk57zk߯1K~Uݳ}ndGds:`]Fp@ 6d8,_g޸mlПǹHpcl0q >gҪ07̝,tW:iGBFvk4!N [6r 1TB5: L8g5&;b'*j9π /ù\\)}2Cv C.qܩ4EިJ?We\cC}%%h2}/ tYs 70hUVOPqtx.O:w"R،aqzJ}NdUکVw a17CQ2ކZ^qLOJPx+9D}%SaGX\J1$x>idvZYdaǭe}-Y6VR"W'c<{cOCڥvTv#o-O[[lZr,"[1% n0n%4#4A%i =>}c,ch @;A>?N-G5Z<9O@c'su1Xܘ>-8^\_  SjUGΏV,Aɸ`Z Y4?PrQEC.j8"-`lȠs3Ŀh8"M<mb@cim_i~t;%4] z-0Wd\KlO\HVTn: KVQ\(A6ЯjlE5 wEy1qKIj*xsˀ;yߝ{aCr!/p>2t1 đqȠk2`{(X1m_6BޏDr#Z?Q1Ȃb9E+wFQapxl,\{\q n47 G"'a/*͙=Νؖ-RX - q>˨M߈AX9h[xpLEƾ{URht+i8@틼sk T4d$RtD6rl;!0*85T-%(8]|A߿ a5$b")Ʀms&<!L&s͉p,+%)3YYZA_{k_͊ bqȕ&sG\G[ N:Z|/OՌ-_EZW}4v*\fHO%Rn(kc8sV@V$2.8X)5+ 1wL:r_}Gguđc2 kJ<$^Gnp0g,C!9\H~T8nބz"i.}8(_‚ `7Fx} aϠncȼnkSScU¼!r" ֍gn9v^^:@N=ز4H`V:25ΞDLk]r F;$mApnjC+;6e&"A+gH +$*O0펃J?:(5 !L`١Q7ՎH;5W򎉊N$փd0&ʖ>ɗ_CNݗӢE[61N\6^Nj=ݮv>-gS.ï5>]RR'(](ƒ- r]M l-e[fuI<~?{Zkq*i)NԪ: AUPt,3F|1#M*=i `($Cnʼn_Z59SqA֋bCyxuH6ɡ CW4O萼iڹ!M['gy(T pOt΄5@tK/mefR+͌N.ql  Wwjs0Jϕ_7<}yk};~> >PnU0~8Ԣñ4OHKzĎ0{ ʟ48n&pݼ󌌐hBq"NW.6fg͡K]JKu`Կ UvCFtʌX6Bj\qf烉|Qo?IDHg$;e(VqHǜ~XjPqŚ+ĺ0HC#fsQO`I1a$#fƞ/fq?eI<$[Ma/N:Y$P.n4FI*'1']!F9\^, (> |]?6\Vډ*Xah^0/E.,h%m 6707L0%rQT)Y_M(YI? H ZQ0ՍfKYͽ /K#lS5drU|(F #i_iIΝAr$ M  $ic6OE=O4 f,p߽Yh>+Ӽͪ@d^ph:kMC ;IriAAl^ .b5 ͑K%)m%|Mj"l FY+˗Յ(XY3& uFR|Q2lGAڂ3`!+,VD&1>֊9? ĬW_o:ƏT=4)~Uऋ &p|mnj&|Rq G bH,Ck,,W`<5 ;@6+1ÿp`/4I;P6TGOzPƖnȮ[:@\-oZא QQSAUBjDntq4\&KDY{AYDLUFjUM$:/,혹(K `nݽj02FH:0J wQ$y5R_Чf)?t7\^0ղ:`861!v{Ee=2+z'LfK sĀjNƄc]є+PdW`<[trn1?6?_e @[gLKelnI r^c,؛G1Wq9e&[\iѭ \ur2 ǘT\.{ O#R~Ф9%329hrG5X!-Wi.% YU,[YmpjtLKfEjrՠ(v぀~dv2Xki7Ō,b7ɬNeͩ*z%aL8fJ'1ry7ͪAf/59]=f3M4uHf{EiIvyEk՘~yuXo718ۮy"Tl )~8^ ,w"Lu-SE7EqRU?`*I>T(vk{GhƞTqa[SU a<ᢺg'yNWc,Odt4_k^5lI;Ft4;Ų=ȫg2x7!;j|1b,UXKd> "x5;nEn 㙖l$n:3A(z_D g)%ڝI}4:at =a<_Gi'̇aG&3"`7ډ !C|ODtH_qX& ʂje ^T2͝W7 Hrѧ ^2P1gpkn@_ʃA9f KCCQ/UaD y"Hgɾk]d~5KX28E.S298GL}0(ۭW_Huixo NtN0C|Oa_Lf^ݎ88G;yw }CgzIcG<1uDJ'rnv穚WdWފadJ +1i4m9qzP?ro'g&HrP&?/431s8Kż6iubL 8-A FuiY8:`Fj#灝Sl2%~{AmڮhxC=sP=ZzlyWJ~A_nֹn[fCw@F gY7ݥgw_LE PzM&wrTAj2FNc"c<7MC@p]^&@[&fW4'Gˇ(ևv*lo?[aN!s즬"Fmk,pX'j&x ksQp:_9B~DU}UK7#0;[ cJXV\]ҵnć%My4*fyW7_xŭ<̤D.AaVLuB2f  Q A~Et9(,wDž:Щ{5f5;@VmA$l~go2v}.u vS`Kla(-˻EVsҀ9e ;huSV9lvhw'Rpnb\~ޔh فztó}|ԉzּhy @3SWO"@K$Y!AٺG&zo鴝zAG+WcI ե?0Uup% )b{,.O,z;%S;z"% 0|`H=xjZxLR%ʽ/"JZW5KRMY`ac4@9(gcHy ' Xߡ"[4S|94mgÙFO:]nq-)Q>{D 0}X!>+HׄdKs.`u=ZeX'g)~(^$b`l ,jyx;T1@j.̱Tض*(Fi7{oǂ%%MUs3}ր5,vwi߄08q,u8MZᆄja@P  E;Z7WdBn5zZh=d _"m4ȁ&i zZuJ늟+OFgH~ z[cmӳI:8|bN}hJj^:fr`֒&H[rl6]kIS~Q@tG3d-ko#Z R N;5r^[0K&/  MNqWWb*:fP#)GRJ ;F5k]g{R\QCq.Y0Dhgk[M\`ZUXM[\dYrhEi(v"@^]Fo91cjh0fO9z?Yy7sW0+R!`j4ŌiOq<;%Z*(Y$Гt@Fa䘽mC}VogF#^< 8H K;a\ a4wPlrz1%muR7jYS"B.] ueG6CQN̡m⛬b]huu'+5E1A%c}j7Ӄlw(qk4%~׉*].@ Cq?7릥(Oo߬;;zqՇB sάި͓Ӹz'f|K]c'wDʺ!=^'ēzl'|X!穔a;D-K)M~b)'q+ `WR~FZh|iZAGՠ{8.~} de%HG.z(tQ;22w*="zѥ4Rf%C >V 0{Bw!Ev]+uqea nm&)$4@}:㲋]$qSXs2tZU @<J2MUr{C5(ĵ L(4l${KvPi9ȏɋz?1`, ]2X*.]e!!(7{̟q`u3[k#e@A>9X0&<8q ,ҼjNSL>Aa=p]o2!|Q9$WmsݔSJ@IoRL׊!_9X: WI38tH}G@ ɤ!2C5\l*eʝFaEx@T^yHOS<XΨ / (,KT85}Qw̵sj b K MPsȰV熽ZDi]^vVE{@ȊK SX\p+'+}>W3 a *f-AIP1/{NH,Uk{qOVNm )MFn X x4(B{ku6nhʦ}Sq鮨̤e~g8+';9&b X#OgiKCԼ1IB齃U eSє jNUʶ~^Ep $RJW[0z8j ~@(g$WZ c(]lS!{H| ->_ COm^%M)BO;d \H/Gl3ʤ[=[:!a2Q[*1#򐹮eK<0 W#hTeKtd|ZzmWK=ihKJ &m9vgp.E"}N|Bny n{DΧoYq o{^wFkiص]@ڵnhռ OˎU30X #i뙐cm).m٭uin_|٤K'^tU8,t?dg~ v> tTw]('h#yLBUa,;fl2i?RfFIV#N>[B>(RѿfpJ8.TQ13iRQjiT~LZФ)j=NE-D4 X쪓7%|RDq,^DNsF&P,v܁8حܢ -o[Id+{3a6$ 6}(0QHE$ȪvbG3F<",Ѣ[r L\R"EϲMs8n6@d'ʲޭ&".|$nw.E.S^S:E].[8nAjV@J<[S(*Sd0V;&boU-+$CX oe-^/H@äE Sxlf5SfE`dYEL;FRb #n0 9ƆUF)k:}D2:" t$,n ۳Sa1I:dI9.[^Ft[$2)8_`t^YPS] vY*ʲ -ٺCg7?UbQ9Y71^Qɟz-(4:q4J+{ߡNv%+bٛ m`0P&Dsg$_v$⸜'JOęBaqzv5{Asݴ*bRBv]f쾯!Z/ ([\h]+H7)UI{=/X.$ՆiӘ/P"ui!IY^h<疲B\qE}II Gbx+GD[7p8X8o>EG!-`eB]!~Mze"Rb;xt O X1ʪpRbW,)ኚ)̢c)b ~ޅW5ϑ-" RDↃ\i*n?t61`ӛԬ"t/ko>".U$)LԐd;M$= R"/q!l &YIII%CZ)N8.t7T ͞B䰉6m樋TkMlF똚eSPH‡[ޏx&6`/i*oT祿9jq^Yȵk0AQ4 ~ӄ%it\|ڠ,@u 0U2ͰHWܲp:ML|3Ujw^…[i,P*K  S!Z`{*WpCe)vRfez^_ m:Ix)2gff,-n&NYĸ28w=1 21?%e6=\y=Ut(S4#ac]N +b$Y"EnZ'BZ'C0Qa)Z");nhFgfk톰q,k0BxRjWМ]l=xҫehىHȈ/ %[~t~Bp錛JgK^UH!\432⥺HgG,g=kKX3;,(d&vq]&{bn]Qң&Z뮥zG:C:-UgݤU{Ft)g *0L`W:R ˮUϖ)' bZō*QŒ(b S#KJxbk}Q}rz6^Vlbn}۲m sG@O_gOFKߖnϲ}( 1eWQ5sh.Z67dFj9L5?\Va(XlU˘r6k^u~$-v>$(ya,+QbVaZ1ɲS~zn8. Lp@G*p^Y/qR^5Gt@> |WqTS"ßPz0r5 U0ykBD$3M@k%;pbL*J檗7zz$LF>tZghddYr&jNA@Af)'JL5>XorRRßG,uy[58K9b>١oIx9Y8^r-"\4"2CFkW6bC<]77`{첏ʡ}(ڳ 'eȉU.㞺%WZ+-M8\ w&d>= <{㥵!^[R+nN;i̪ unBYVU"ل8:~d%< +|Ae%KeijYyV&y&V DZ&4Eԡ1 ̀h;%GS1iy+~[;s^K~m=׵UzCx>n8 6ʆa(y ~]D`*z>c|<=x[H+C 2W#V_SFEfWK3Q՟xljBuD6.a%|wBLy;BXa"_u!rM6OYíλ BӻDբ<w*H{)o%9hn,:!2o|Gf}*'.MƍIw WKTqTN.W MˣZ!ŽB)ll opYKavݡK&}Y+PQ;:{E{o|>%\w%~e6=m7[6( rRJg~YP͉>c5һ2[!WYҫ2kv5b(p[֓5{d(5avv?&/#|Sj/+|8mV|h̙#:|Ŗo_:6H%ph u$銥)ָ> 6C&H m~\DTH9ֲTN/Bg%bکv(0>yo4UuPE GuR:ܹen ,o1&3׮'AtIDI^=c_ tbW۫X|Z, {fs5Bc0WhPNK0 ١XS xƹ3}xH#Gˇy2An:[\ĨKU<T ,$!Hv^{"$Y E˃nL5ML.cW>ᮁ{z+_J'f6#r9ң/36bz"wO뀁KǦ0t5@~ߑ靚+ z\JE/ql 1?NH zc?Oo큸w,$m /ؘ+du~@DznV m1흐]~|YY5DAgtr[1851)>l - 0i}EՔ=dO2uHؿ2 Rao۳Ky_bҢ?zSbj7YQ '0Zp$ʃ\Ӯ1S`kiM/,s7JĮDr@Q|\e<'W%m VYфQ"fE've$tqĆ#A m(V3p׉BI^G{P%/jܤSn>M>5 qADsG6p WxI,`,Uf>;Bh\3*PBrD)':iǔ>RJ.UsX&ݼO9z<#%fr#zQtaKmv8X}GbH >`5y2fVdT>cfnݲt;uؚ#t˸e ȕS*p7:8³QeA :QՑWLuW-RTg( dב'ۑ",bR`‘ɔq% Oe-Q^r'qWll4O$N^@&iQŒS'=.KEOO,?B/>X 7iQ#{p}b A(SNAH񯅎:4CmX@%SEO'M܈}Q5{un|Jvr{[|i09psQ&$5^~W( ;D7M@r3!p]b2LWQokz3#p71fJkzb:̅Rc5v}ʃrj|!4.ܖESpR@Pqq?ҟR&X$jQO cw,{72W9S{DSEQ-cp.UYC)zՋ\zTJD nj( %'{1/Iس5"c!n-mr2(Y\J+`H/3)n"+Sx($Va/M=^僋 {b1W!}STcc-tn ̦xUa];HQZ]*y| HJF\= (x~l/U49%#]0P |'s TD fojQp--+?&G3 ę0&d+EJod˿ZB w. r(MwErrCIɊfm[wumyAؑ>"8gӲl.괚o&&*X3payXd~b7lkb!#v#IMOdtVI!^N&㴶/:f&WF.)r /Eѓ=ZӠ"7 `r&ʫnቿlF)_T|7!F||H:Jx6Tt{D~P2K]g>6=iGrf3h'aWkS㠮+`#ñ8((r<{VFeXUԕ#7cb9Sr[1J*a D?||o"p\J͒n y۔^y){&|0M]zdZX tm l2wK0mzt-l-.ccУ"3ɧwriۉg"v;-Tj9zZ+Sw/=nO;(/ł<8_xV9DM WC0%eHG7ASNǔMusآϩS7+y`+x-r`5!lS5EeQ,_Ig_҉{cWt"(zچ\SY~ʋD#f)c١Om#eۚ1Eg D)+] ^r B~#Y{XÚ6GOk\%9at`FN)&{u&[R3~}*+L)TtA?Yb05=h?zHChZsNZfm..;YjRli=b6+0.S1d,q<&6!^<[fMz}P8ub#BVwVU&\-07!<Qf{,rgcmwI.b;U3B3qiB9%ElN8hӒmw4]N%0cև(xy\v>Ǫǎ0=n1mgvpRv%> R)zR }Iy7tE7"s=0b0*d3x5"0f2FZ iYߖ.(CP 1~vs=5BHɔ5z-~1a LׇMY}0Xr9]떝H߮Di7`deCт;jh"NfE8E ?L&0 8 ΜB?붴VEx>QjFtn"B:FtKJ@{D8ƇڦObK#XUAΪăмMhԒvAv\e&`=uNɬϦP%4E}3ٌ\͆d37<8L}~N9ϿCLƢbם"}"OUvG(6`3ٿ2Mpd132FO[^40Ve^s}b fFCnGCo:>Fۧ[2MKgr^9g%"aƌ ΢ٻ^FL3/pp̸U=Px_\8+;B vp]{JPSeԶ ZOsMm|TI;j\=E*}ۮ ܜҧműLiPo>MM4zTawo#, pd!E T[ %Nj}2OX <up(Pv(  x)'H\k$/0nY'eg1%EvzJtKaIFt|,_-?3<ѕU+՟ ]pgc]g)5AI_W8;Zau1B6SϻRܟJ|)ŀ0 7@3sDR1t~MzHj5?m'Y,mu4NUOSmgAQw{:C|`-7Co4|m@9M=:\@79zU LU{U=+@[D D<I<<Ώ-I2fc V@>YqP}' F+tXLIHYy>L,Bd#;9pkU;d`Yx2 ~\^bk"= _+{J~ҋk6VVtTC>NLlAS]7RӉ9r|,#i3UQ8W,J#4[u0089k^7cf{lB6)Yil፟ ud,ة@0}ZjvٻNP׍I+Ocue\xE4 yGhK#ztQ ՐKqƻx 0XRH!։GJB~unRr+X)G&LJW{LXڇLo^'_"!:1Lg657M2N]V=7%5m(fQ֯0ܥselu@_?6>q_K-n i|dpl B{k3mxDu ,_lMͶ)7V̾mSR@Bmsmt"Ͷ8pml6 >XeuEol[\|N4MBx2kN1]^﵆|mIIl=õZ~bm!Ixæ9mhmt$l]ΚYHL4BO\eO,Eݶyw&Vb4KI"> -[MF}څeڅZ,eMa=%|?C8BAma[7-Ѷn*г>m|Z4{e;=yLLZw_X*b_. JrCv!t +-QC}b X1-(yPۆΪ؆Ы>cfB> -_`:Ch/n¤oD>w[œO 3vvɇf=1c;j' ^_D/4ek':Um.9e)wnV#V..|ډT\Iډ8XTaJ ډNyFtV:߈tS>[.xy8`6i17(b{՞c۽)jF2[O|2?n ,V[~8o7۔}PW|n.R!K1~R  p<~d׊g,| VvCu5*3iɖA> eѝiA+ iU&/PZ q+LF$Df}e*ICٙ t~ǺY({qě+)y91_MmvNCrv_mc;^ۭ~@ƤY!y`w Qw}'#K2SLILBk6 Bah0`h@x9{#͝ Sb,s1Ia ˌ$Ɯ\!+nvr ]#6unY} OD>K|6l&pr˄#c]oOCp \I8XgyGX|&Gk#?)w=ޣv#<$But1*$4lvSs611| !ǛyMpm6$O29n:w2v }nybp۝>^0TB%&uM+Şu 1O$6_ vOm0w_9VAe Eūi2oe*2g^}&O93Pnܜ^'ӜR^[ jD,71#ۗ'״4sK\s(Ru, 8V)kތ c4XOo156ֿC 0R /jcCCo0&]1oԔH\ً)!!Q?ile ))S/n|k/!fN43Jnᡴ3D9/]/tg07?p!٧GzW+Xo!cjbt󓻯fŐ1/zO4ue,pb,lD*C߉\S~e*lni1PB4U!*Hʹx=s@0j*El)J.EZe(WOӦ;T\ ,h KaG YMܛlˌRG%{vS~Z'SY`xځWKr$ׂ2|C.sOO3̃<2z±/1^? }h ip*D8ENTPeqgKP'M+etCɁ]q֔i ̎wc/yScE%/grCuh!xF$$]q)}oݕ;2 O݀iiJLO"hۋ̂uTc@ӮԼ] -≍<ʽYy<14ʪhz2KAl kpQ K?agwE0!0*$ dʄ& n9{KWղbgƲF cheR1 <@Ӡ؋O 23'ň 0YW%mA+ z @Z[/QJ_*^du񇺥tϑl:7٠}7uDKu(yÓO([`k lki۵G S3wYeD4104ŨPiD`փYYxMJ2j7`v+$oJ_}j~/|&}  岐O_٨j٬$bȐ7ibZI=IL=뎃ѠaR5v#v},Ӎ|OO3CzDŽO8QXCs>>̇fNBp3.A7Y$5bk(͈mCGw ;kM`ĊF}ne˓=IUtzFG껙fbWFR2Unc|^b7 ߧ_p8Kt-[)6n,)`xSqZ M^)JaEo2^Ynvy3d%*,e҈%|l8U81I,FP4.ߧ4!TL'i6;1LSg{91fy*,%Z/e_+9l9*2 W-D jT/ƌt#5sbk4Zsx4$m''Oף8g#_i>aty'a/Kfrǖ~%^apLf4G|9,UGɩWK?1cޫ"=a{/qI3aESœp-nKn)6EӢѱ59qs<襫fW䢃>趟ƚޭJ}ULw Beʿ{g6'0J3y ]Gd6zUZ K!Zt)DOZ esRX?<þYҲAny>IDžf뱈\$XE[ Ez±1Xb>tꩰ"ch\Ԝ} #Ij$3|͗͜Ͱ#.Qܔ*q!Vӳ>q%ls7~c{M77ĂˍMר2x=_!EmkAk;}:otJnWŮ/vD~ϯ0I'P#bzSURae!;uCRSRsy:5=^}X`,~VyD_/-/`(h6Q ,me5f,⏧cǒ< ˲jmoĒ30cA;6B85pcA2,E`݁D"x0cYe}y޽ +XyD7 >Kr-y^=6'c(Sx޽h&YV Py,i6WA?&,@d9e͸T$X@5edq6m}$,۸@ a@zp;dhcb|R~x󒴁< VZᕇx_</顝rP-!m@n#xe,YJ ,%6,e#>0/ %耺g'G_>8磬 $V5˰20ʐڛauTYfN1^F:IƐiڌb׮ $@ADoD,BFo5;썞) 'gJ@1P?z蒭T¨Α:%dTA,zכ*唝 M])7Se2WJW`ԝk{+VaK-B ka1HHFI'/Z"O֙s é1 : @b{KArflniם ,z`c}/qv_/C*sˍV g뿅:^2([p8Xf 00s! Vp-W*@eL!t0R$\?S9^7qYa!ݾXًm9`2rNKd㗻ŸQOٰâgEQ#d`mj݀u?s>P K O{<,iMʵba]сA<'wFV CD&g?q" 3`WEfJSêt:<;Bi Xʃ&\DR(*Pqpn C ::~ yY'C9,1+T*4y5~b"dN.29OeBM?[*vck*Hm9z#{b|i^VύZ(c+x`ĦWWh\dJJ ؅%bqclO|amI;t&hxPTvh k` NSm둅[ȏwOF$ g@\/{r1;Nb3+um4ߒSV!^g"bSXq_%qCo*3΢K%YeW'74E[YYH9dl~.=zJvKDzb/v) פs PU )}jP^HT+#f'& <3m[cD_ꏇӭjI|k2eסOFjNrԕX~CdXW4vf6P,dXmJ{5^5`stgmT_?X?2'Ҵ /B3P@ ;y]{4ExK/d13 %0b>* 8OF g27ʭ!^ٟ8C?B {2¤0Wq17M#,P2rclLlÇ4# *k9s1ZJSoxr+Rvm30u; >+Үc58Z!da>ʱ}-3 'ӷUa0LVđ:`@^d# {<3ݻl+;Y+;PKH,[G=?7VsJF/'d+kȽ =J'ҳQZg1Q'X^%ȿoVOKA15{X zdG i-4 zUs1㭥?+sNx Eδf6NdwjG(OT wݡ;-L9l6R0'i[f] '"ߴzeVbRJ⡣a[>d{><@!Y(<?v@I39K_[鰙儃&˙rN#f^`{?zpl_sZHԲiԞˏeeޞ Ū]hޛ Bh7qض}IZ&']ܻbŽxwɽWk9r~ڵv#gtuaM_ vvNK^0eN](s;GR0k! b֌d|"CZTQ{2F2 HtS{nʑ]KN^7B9w)^zсV9Gs8> ޥ'GBȹ"^]# Vu0} 6 > ͝Zt-ϽMK{ydv1r;`.l|^|zZ g5G!'!sܹw(n @j_pxMW䈴@%}t.cBSWͷ&1w/CK]ĭE S\J4Xe؀~j52M!dFJĦz(,m0N5[isoڃa#у?EǷťL-[q¹ஃ&(uj/&f90~󑦬$YC58t&xDx@nMP/]h^?  2bKW:$/D-SW>|Mss'ה8cۺ3HӦ~İ,\ r>04%4m282鄶: 5Y |GKwc@E00,;Ff9mKxqN[Q[z-!`X. ˭q?;J}ު(Ĉ& ԧL;siJ[#2u#n}?8)s1x=+w'y9$t|ĈJ/NÊiȷ ДXN["٘v(&ӹKbFgRI6\t@n+;pGf:t8c[fʅcPO Zq3Yh|xެ{`wqQ$ib1Rg s$lbYa}v߯-EeN;6Fۓ~r*'ij" (Σ/1ctY՛HզZ!el8@= 1\t G%+W"VSpˇFa|ӛ CpXHByQ2 cp6hX7s[J}~,΍RJ}VT9ZBB/nV` by B^F"rI:f˳e7ta~8VAgsAh/fwVj2Q~YYW|]Fh=X)'8(ӣ?pD[+)}OG2 x)祖l-ʑQL̗&'SbN}3igz'u(u% uR5lñцD l-B+(ߊOwf{{1dȭQdG|:,/} 9D=ayWzFDHM7KMeZgaCą WrYTP2r2[plzcu[eJ\-Rg =_(if#$~^8Çʛ4%r ,!ȥ6ֶ,OMIjT[DےvgCy2|_1r,\qXhQҁ x)>X36ͥ#8r:^L0YSǗ쒤@jWUǵ#0f΋P'Fbbab~$mY)E5gӟW~"6EtMV3/mQ̾E1G#,HbSKSM XQ 5c9\]3]=1zyxW " GrYؤ1BWJ"I+RlR̯I1abTӤXG̣1Ztgh<ŷ5ĥ֊ȵT^jəTRr"3fr|}8 }WLEKr xj4cbVz͍7_b8"sT8i6z9 ֜gL =^̮>941"0`B+CO!}@s55 {/>\, ^8*eU3F /x^kY` /jqyT=nE=IH|nE#F+!В\N! %;*֝fU]`YO'l4*mk3%3Km(}"|+| ʈa ZS`W'jEF^!?ӳZMoj'׭z` )#$GѳL"}"`.:p*at.RڙJҲ)tmg(%QC`"m_/ʀJZ~e|6!p$0A$N GEbϓYHfq%b%FPVcfD $bG"> '4ɞq$&'=6'l&zrޥNȦnfcHhDp*'Ϻe3yaA3 ?b>Ŷ7*l{(+\܈ō[5 'merF-aF6݈m7eى>DÉ#]e>DP aP1"&>ąC">UC-p2ڏ;~K14D39cFCwrfJ!~AF]78}ݙboٵՁf󕞯0iEbdo3 zZ*h23Z,Qv F d#{$R$@t٭Dg9CtS΢+h|3q%r"ٕS,W3()#swP"<؉wdP r-lEWϢ>1m ⯤FrdǢ eYh} Ú~eqIY({Oʙy?Z\X\ ENfxTeD @X C("Opc1k<;IuJU}=8(]FY4R\2*BP4Ad;a1?SX2nJDI^C6*Yde2#/2h-wI:1 (NCVCI9ID;-`+F@Nxq.(DsYOˇ$nVcR03(Z @V;/4YU&욭zΣi8MQ9钾H`1nk!EEj"',𢘄_a襺[?(<H43cOTWE'jЌs-1ዊR,jIO^aW+v^ {Np|!{po³dC+OB!y7bV7+Hbnd j8Wv%tJEṋ&إex 򒒀k,t=S辍ϭ|1(~ ` KS´ Gp|m#Y;RjI !YI=3ohE%⥮]UT8W297vq꒺DxݨrX5#70X>uU?SSdoSNPfACNvAhZҶ1qZ`!"[9~C0Q4Yџ5SZtFW>a—NRB6Lڟ߈]&cbI4fUNcNͭ[=ZdkM7(`tlIj]ZfE)Mؼ}էORPۗ dCm$7̭1J蹊kPoq֏Pա_bڃSu;} rʟ[יs7\"p#];M7H^K l̍˓$WĕOWe_)zD7)A7CQc'3UG Sg0qEi }OMpA:aFw!'dյk@,Av y/kλdTk;K ld'Jd])]ɐ[) nY$ 1ŋBUu I{s7r{fWhؿiem >AP;kZ);4q(XI?⢧%J-* m+oko*;{z瓪y^s\d=ukz?P[N_|ٓ>IfVt Ip"Brއ!޹3&*ʵF/iOQjɇxv藃/I.Gt! b|k/Z umR]+CEOGvU^: L3 TPuk8#Pnp{D^Hu\rUK|9u{$OB׶&(ޢ 'FlW٥):d)h^Scho:ŎoT/3N)Ɔ?q?FN؂Dt؃ VR޻idsBDACDCbX5~tce3剀M(@Ԥ1}*o`O5i޴+@kBiva0mHf@ G|X[0Wig3 #hȨ?y4BMD/aAi~OT`$xr ޺gԽO*؅bI 0tRIb~q, / >G`T]L` %aFr&tl)Ґ~I :Hq9 1_dV'DN~T1(4d_:4͇27/Mt)AgOko;+~!@ |zv!X*nc9dyn< XL.l.R3 3 [pnmiujUz_$a*۠BOg  Hq `t^ h nYi#am-$ШLs0pdV2҅dbC5 jɭC\ =%a˽OG0tڍox?2KF^[so5Hд7-?w*F܏4m15VIEql9P^UpvĹs~|p*᭰RA H>2Rr0`XZVBGLK8la٫kE2-9~fF1(6Q)lT/V x50P3x雝 푔3VRkbPhHOabDw Mځ}aZ#h0aoBXZ`qJC0$ G 8E(a'dm.&6L ް}'a_q"W{\yt k"Zݶ{MD^#F^(hF•CFpl*Cl68ӟ4z8e=$ψ0M=.t8g0e1CYF 35w> >> >> endobj 2 0 obj << /Type /Page % 1 /Parent 1 0 R /MediaBox [ 0 0 200.204224 302.29306 ] /Contents 4 0 R /Group << /Type /Group /S /Transparency /I true /CS /DeviceRGB >> /Resources 3 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 2 0 R ] /Count 1 >> endobj 6 0 obj << /Producer (cairo 1.15.10 (http://cairographics.org)) /Creator /CreationDate (D:20200702143407+02'00) >> endobj 7 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 8 0000000000 65535 f 0000040384 00000 n 0000040153 00000 n 0000040081 00000 n 0000000015 00000 n 0000040057 00000 n 0000040449 00000 n 0000040724 00000 n trailer << /Size 8 /Root 7 0 R /Info 6 0 R >> startxref 40776 %%EOF math-comp-hierarchy-builder-4d8a939/examples_stdlib/Coq2020_material/diagram.svg000066400000000000000000014363761521677141400276120ustar00rootroot00000000000000 image/svg+xml Structure Mixin Factory Packager Builder V1 Monoid Ring V2 Monoid Ring AbGroup V3 to_AbGroup_of_Monoid Monoid Ring AbGroup to_Ring_of_AbGroup SemiRing CMonoid Ring AbelianGrp SemiRing_of_CMonoid CMonoid_of_Type AbelianGrp_of_CMonoid The puzzle pieces (mixins) Ring_of_Type The "virtual" puzzle pieces (factories) The hierarchy of structures math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/000077500000000000000000000000001521677141400254365ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V1.v000066400000000000000000000047601521677141400261220ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Left mixin in Fig. 1. *) HB.mixin Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of Monoid R & Ring_of_Monoid R }. Notation "1" := one : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. Infix "*" := (@mul _) : hb_scope. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : Ring.type, left_inverse zero opp add *) (* https://math.stackexchange.com/questions/346375/commutative-property-of-ring-addition/346682 *) Lemma addrC {R : Ring.type} : commutative (@add R). Proof. have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V2.v000066400000000000000000000045551521677141400261250ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 1. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Top right mixin in Fig. 1. *) HB.mixin Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {R : AbelianGroup.type} : right_inverse (zero : R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : Ring.type, left_inverse zero opp add *) Check @addrC. (* is now an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. (********************************************************) (* This test from V1 FAILS in V2, and is repaired in V3 *) (********************************************************) Fail Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V3.v000066400000000000000000000072161521677141400261230ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 1. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 1. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Top right mixin in Fig. 1. *) HB.mixin Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {R : AbelianGroup.type} : right_inverse (zero : R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (* Left factory in Fig. 1. *) HB.factory Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context (R : Type) (f : Ring_of_Monoid R). Lemma addrC : commutative (add : R -> R -> R). Proof. have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. (* Builder to the bottom right mixin. *) HB.instance Definition to_AbelianGroup_of_Monoid := AbelianGroup_of_Monoid.Build R opp addrC addNr. (* Builder to the top right mixin. *) HB.instance Definition to_Ring_of_AbelianGroup := Ring_of_AbelianGroup.Build R one mul mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : AbelianGroup.type, left_inverse 0 opp add *) Check @addrC. (* is still an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_material/V4.v000066400000000000000000000122131521677141400261150ustar00rootroot00000000000000(* Accompanying material to https://hal.inria.fr/hal-02478907 *) From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Declare Scope hb_scope. Delimit Scope hb_scope with G. Open Scope hb_scope. (* Bottom mixin in Fig. 2. *) HB.mixin Record Monoid_of_Type M := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M of Monoid_of_Type M }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. (* Bottom right mixin in Fig. 2. *) HB.mixin Record AbelianGroup_of_Monoid A & Monoid A := { opp : A -> A; addrC : commutative (add : A -> A -> A); addNr : left_inverse zero opp add; }. HB.structure Definition AbelianGroup := { A of Monoid A & AbelianGroup_of_Monoid A }. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Bottom left mixin in Fig. 2. *) HB.mixin Record SemiRing_of_Monoid S & Monoid S := { one : S; mul : S -> S -> S; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { S of Monoid S & SemiRing_of_Monoid S }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. Lemma addrN {A : AbelianGroup.type} : right_inverse (zero : A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. (* Top right factory in Fig. 2. *) HB.factory Record Ring_of_AbelianGroup R & AbelianGroup R := { one : R; mul : R -> R -> R; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. (* Builder arrow from top right to bottom left in Fig. 2. *) HB.builders Context (R : Type) (f : Ring_of_AbelianGroup R). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_Monoid := SemiRing_of_Monoid.Build R _ mul mulrA mul1r mulr1 mulrDl mulrDr mul0r mulr0. HB.end. HB.structure Definition Ring := { R of AbelianGroup R & Ring_of_AbelianGroup R }. (* Top left factory in Fig. 2. *) (* It is an exact copy of the bottom right mixin. *) HB.factory Definition Ring_of_SemiRing R & SemiRing R := AbelianGroup_of_Monoid R. (* The corresponding builder is the identity. *) HB.builders Context (R : Type) (f : Ring_of_SemiRing R). HB.instance Definition to_AbelianGroup_of_Monoid : AbelianGroup_of_Monoid R := f. HB.end. (* Right-most factory in Fig. 2. *) HB.factory Record Ring_of_Monoid R & Monoid R := { one : R; opp : R -> R; mul : R -> R -> R; addNr : left_inverse zero opp add; addrN : right_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context (R : Type) (f : Ring_of_Monoid R). Lemma addrC : commutative (add : R -> R -> R). Proof. (* Exactly the same as in Appendix B. *) have innerC (a b : R) : a + b + (a + b) = a + a + (b + b). by rewrite -[a+b]mul1r -mulrDl mulrDr !mulrDl !mul1r. have addKl (a b c : R) : a + b = a + c -> b = c. apply: can_inj (add a) (add (opp a)) _ _ _. by move=> x; rewrite addrA addNr add0r. have addKr (a b c : R) : b + a = c + a -> b = c. apply: can_inj (add ^~ a) (add ^~ (opp a)) _ _ _. by move=> x; rewrite /= -addrA addrN addr0. move=> x y; apply: addKl (x) _ _ _; apply: addKr (y) _ _ _. by rewrite -!addrA [in RHS]addrA innerC !addrA. Qed. (* Builder to the bottom right mixin. *) HB.instance Definition to_AbelianGroup_of_Monoid := AbelianGroup_of_Monoid.Build R opp addrC addNr. (* Builder to the top right factory, which is compiled to the bottom left mixin. *) HB.instance Definition to_Ring_of_AbelianGroup := Ring_of_AbelianGroup.Build R one mul mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (********) (* TEST *) (********) Print Monoid.type. (* Monoid.type := { sort : Type; ... } *) Check @add. (* add : forall M : Monoid.type, M -> M -> M *) Check @addNr. (* addNr : forall R : AbelianGroup.type, left_inverse 0 opp add *) Check @addrC. (* is still an axiom of abelian groups *) (* addrC : forall R : AbelianGroup.type, commutative add *) HB.instance Definition Z_Monoid_axioms : Monoid_of_Type Z := Monoid_of_Type.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. HB.instance Definition Z_Ring_axioms : Ring_of_Monoid Z := Ring_of_Monoid.Build Z 1%Z Z.opp Z.mul Z.add_opp_diag_l Z.add_opp_diag_r Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Lemma exercise (m n : Z) : (n + m) - n * 1 = m. Proof. by rewrite mulr1 (addrC n) -(addrA m) addrN addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/000077500000000000000000000000001521677141400245735ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V1.v000066400000000000000000000007611521677141400252540ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; (* add is associative. *) add0r : left_id zero add; (* zero is the neutral *) addr0 : right_id zero add; (* element wrt add. *) }. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V2.v000066400000000000000000000010531521677141400252500ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record monoid_of_semigroup (M : Type) & is_semigroup M := { zero : M; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition Monoid := { M & monoid_of_semigroup M }. (* is_monoid does not exist anymore *) Fail Check is_monoid. HB.mixin Record xxxx P A := { F : bool }. math-comp-hierarchy-builder-4d8a939/examples_stdlib/FSCD2020_talk/V3.v000066400000000000000000000017601521677141400252560ustar00rootroot00000000000000Require Import ZArith ssreflect ssrfun. From HB Require Import structures. HB.mixin Record is_semigroup (S : Type) := { add : S -> S -> S; addrA : associative add; }. HB.structure Definition SemiGroup := { S & is_semigroup S }. HB.mixin Record monoid_of_semigroup (M : Type) & is_semigroup M := { zero : M; add0r : left_id zero add; addr0 : right_id zero add; }. HB.factory Record is_monoid (M : Type) := { zero : M; add : M -> M -> M; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.builders Context (M : Type) (f : is_monoid M). HB.instance Definition is_monoid_semigroup : is_semigroup M := is_semigroup.Build M add addrA. HB.instance Definition is_monoid_monoid : monoid_of_semigroup M := monoid_of_semigroup.Build M zero add0r addr0. HB.end. HB.structure Definition Monoid := { M & is_monoid M }. HB.instance Definition Z_is_monoid : is_monoid Z := is_monoid.Build Z 0%Z Z.add Z.add_assoc Z.add_0_l Z.add_0_r. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/000077500000000000000000000000001521677141400235425ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/README.md000066400000000000000000000010721521677141400250210ustar00rootroot00000000000000 # Demo1 The files `hierarchy_$N.v` describes a hierarchy that born with just one structure, the one of `Ring`, and evolves to the following one in five steps. ``` AddMonoid ---> AddComoid ----> AddAG ----> Ring \ \ / -> BiNearRing -> SemiRing - ``` The file `user_0.v` describes an early adopter of the hierarchy, the version described in `hierarchy_0.v`. That code works with all version of the hierarchy. The file `user_3.v` describes a user that adopted the `hierarchy_3.v` and that code works up to `hierarchy_5.v`math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_0.v000066400000000000000000000027231521677141400261320ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 0: +Ring+ *) (**************************************************************************) HB.mixin Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_1.v000066400000000000000000000044641521677141400261370ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 1: +AddComoid+ -> Ring *) (**************************************************************************) (* Begin change *) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[verbose] HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_2.v000066400000000000000000000066711521677141400261420ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 2: AddComoid -> +AddAG+ -> Ring *) (**************************************************************************) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* Begin change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.structure Definition Ring := { A of Ring_of_AddAG A }. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. #[verbose] HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_3.v000066400000000000000000000110361521677141400261320ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 3: AddComoid ----> AddAG -----> Ring *) (* \ / *) (* -> +SemiRing+ - *) (**************************************************************************) HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* Begin change *) HB.mixin Record SemiRing_of_AddComoid A & AddComoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr mul0r mulr0. HB.end. (* End change *) HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_4.v000066400000000000000000000124561521677141400261420ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 4: +AddMonoid+ -> AddComoid ---> AddAG ----> Ring *) (* \ / *) (* -> SemiRing - *) (**************************************************************************) (* Begin change *) HB.mixin Record AddMonoid_of_TYPE S := { zero : S; add : S -> S -> S; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_TYPE A }. HB.mixin Record AddComoid_of_AddMonoid A & AddMonoid A := { addrC : commutative (add : A -> A -> A); }. HB.factory Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.builders Context A (a : AddComoid_of_TYPE A). Fact addr0 : right_id zero add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.instance Definition to_AddMonoid_of_TYPE := AddMonoid_of_TYPE.Build A zero add addrA add0r addr0. HB.instance Definition to_AddComoid_of_AddMonoid := AddComoid_of_AddMonoid.Build A addrC. HB.end. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* End change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. HB.mixin Record SemiRing_of_AddComoid A & AddComoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr (mul0r) (mulr0). HB.end. (* End change *) HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Not general enough anymore, subsumed by Monoid addr0 *) (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/hierarchy_5.v000066400000000000000000000150171521677141400261370ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. (**************************************************************************) (* Stage 5: AddMonoid ---> AddComoid ----> AddAG ----> Ring *) (* \ \ / *) (* -> +BiNearRing+ -> SemiRing - *) (**************************************************************************) HB.mixin Record AddMonoid_of_TYPE S := { zero : S; add : S -> S -> S; addrA : associative add; add0r : left_id zero add; addr0 : right_id zero add; }. HB.structure Definition AddMonoid := { A of AddMonoid_of_TYPE A }. HB.mixin Record AddComoid_of_AddMonoid A & AddMonoid A := { addrC : commutative (add : A -> A -> A); }. HB.factory Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.builders Context A (a : AddComoid_of_TYPE A). Fact addr0 : right_id zero add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.instance Definition to_AddMonoid_of_TYPE := AddMonoid_of_TYPE.Build A zero add addrA add0r addr0. HB.instance Definition to_AddComoid_of_AddMonoid := AddComoid_of_AddMonoid.Build A addrC. HB.end. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. (* End change *) HB.mixin Record AddAG_of_AddComoid A & AddComoid A := { opp : A -> A; addNr : left_inverse zero opp add; }. HB.factory Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.builders Context A (a : AddAG_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.end. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* Begin changes *) HB.mixin Record BiNearRing_of_AddMonoid A & AddMonoid A := { one : A; mul : A -> A -> A; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; mul0r : left_zero zero mul; mulr0 : right_zero zero mul; }. HB.structure Definition BiNearRing := { A of AddMonoid A & BiNearRing_of_AddMonoid A }. (* this factory is accidentally a duplicate of BiNearRing_of_AddMonoid *) (* we alias it for backward compatilibity and uniformity purposes *) HB.factory Definition SemiRing_of_AddComoid A & AddComoid A := BiNearRing_of_AddMonoid A. HB.builders Context A (a : SemiRing_of_AddComoid A). HB.instance Definition to_BiNearRing_of_AddMonoid : BiNearRing_of_AddMonoid A := a. HB.end. (* End changes *) HB.structure Definition SemiRing := { A of AddComoid A & SemiRing_of_AddComoid A }. Set Implicit Arguments. (* The factory builder will have implicit arguments *) #[doc="Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995)."] HB.factory Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. Unset Implicit Arguments. HB.builders Context A (a : Ring_of_AddAG A). Fact mul0r : left_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDl add0r addrC addNr. Qed. Fact mulr0 : right_zero zero mul. Proof. move=> x; rewrite -[LHS]add0r addrC. rewrite -{2}(addNr (mul x x)) (addrC (opp _)) addrA. by rewrite -mulrDr add0r addrC addNr. Qed. HB.instance Definition to_SemiRing_of_AddComoid := SemiRing_of_AddComoid.Build A _ mul mulrA mulr1 mul1r mulrDl mulrDr mul0r mulr0. HB.end. HB.factory Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a :Ring_of_AddComoid A). HB.instance Definition to_AddAG_of_AddComoid := AddAG_of_AddComoid.Build A _ addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section Theory. Variable R : Ring.type. Implicit Type (x : R). (* Not general enough anymore, subsumed by Monoid addr0 *) (* Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. *) Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.graph "hierarchy_5.dot". (* we check the alias factory is abstracted over the whole section *) HB.check (SemiRing_of_AddComoid.axioms_ : forall A, forall m : AddMonoid_of_TYPE.axioms_ A, AddComoid_of_AddMonoid.axioms_ A m -> Type). math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_0_0.v000066400000000000000000000007411521677141400253500ustar00rootroot00000000000000From Corelib Require Import ssreflect. From Stdlib Require Import ZArith. From HB Require Import structures. From HB Require Import demo1.hierarchy_0. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_1_0.v000066400000000000000000000006761521677141400253600ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_1. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_2_0.v000066400000000000000000000006761521677141400253610ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_2. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_3_0.v000066400000000000000000000006761521677141400253620ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_3. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_3_3.v000066400000000000000000000010141521677141400253500ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_3. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_4_0.v000066400000000000000000000007001521677141400253470ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_4. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_4_3.v000066400000000000000000000010141521677141400253510ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_4. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_5_0.v000066400000000000000000000006761521677141400253640ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/test_5_3.v000066400000000000000000000010141521677141400253520ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/user_0.v000066400000000000000000000007041521677141400251270ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. HB.instance Z Z_ring_axioms. Open Scope hb_scope. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrNK addr0. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo1/user_3.v000066400000000000000000000010551521677141400251320ustar00rootroot00000000000000From Coq Require Import ZArith ssreflect. From HB Require Import structures. From @@DEMO@@ Require Import @@HIERARCHY@@. Definition Z_AddComoid := AddComoid_of_TYPE.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l. HB.instance Z Z_AddComoid. Definition Z_SemiRing := SemiRing_of_AddComoid.Build Z 1%Z Z.mul Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l Z.mul_0_l Z.mul_0_r. HB.instance Z Z_SemiRing. Open Scope hb_scope. Example test1 (m n : Z) : m + n * 0 * 0 = m. Proof. by rewrite -mulrA !mulr0 addrC add0r. Qed.math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/000077500000000000000000000000001521677141400235435ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/classical.v000066400000000000000000001411641521677141400256770ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool ssrfun ssrbool. (******************************************************************************) (* This file develops a basic theory of sets under classical axiomatization *) (* and is imported from math-comp/analysis *) (* *) (* --> A decidable equality is defined for any type. It is thus possible to *) (* define an eqType structure for any type using the mixin gen_eqMixin. *) (* --> This file adds the possibility to define a choiceType structure for *) (* any type thanks to an axiom gen_choiceMixin giving a choice mixin. *) (* --> We chose to have generic mixins and no global instances of the eqType *) (* and choiceType structures to let the user choose which definition of *) (* equality to use and to avoid conflict with already declared instances. *) (* *) (* * Sets: *) (* set A == type of sets on A. *) (* (x \in P) == boolean membership predicate from ssrbool *) (* for set P, available thanks to a canonical *) (* predType T structure on sets on T. *) (* [set x : T | P] == set of points x : T such that P holds. *) (* [set x | P] == same as before with T left implicit. *) (* [set E | x in A] == set defined by the expression E for x in *) (* set A. *) (* [set E | x in A & y in B] == same as before for E depending on 2 *) (* variables x and y in sets A and B. *) (* setT == full set. *) (* set0 == empty set. *) (* [set of F] == set defined by the expression F x for any *) (* x. *) (* [set a] == set containing only a. *) (* [set a : T] == same as before with the type of a made *) (* explicit. *) (* A `|` B == union of A and B. *) (* a |` A == A extended with a. *) (* [set a1; a2; ..; an] == set containing only the n elements ai. *) (* A `&` B == intersection of A and B. *) (* A `*` B == product of A and B, i.e. set of pairs (a,b) *) (* such that A a and B b. *) (* A.`1 == set of points a such that there exists b so *) (* that A (a, b). *) (* A.`2 == set of points a such that there exists b so *) (* that A (b, a). *) (* ~` A == complement of A. *) (* [set ~ a] == complement of [set a]. *) (* A `\` B == complement of B in A. *) (* A `\ a == A deprived of a. *) (* \bigcup_(i in P) F == union of the elements of the family F whose *) (* index satisfies P. *) (* \bigcup_(i : T) F == union of the family F indexed on T. *) (* \bigcup_i F == same as before with T left implicit. *) (* \bigcap_(i in P) F == intersection of the elements of the family *) (* F whose index satisfies P. *) (* \bigcap_(i : T) F == union of the family F indexed on T. *) (* \bigcap_i F == same as before with T left implicit. *) (* A `<=` B <-> A is included in B. *) (* A `<=>` B <-> double inclusion A `<=` B and B `<=` A. *) (* f @^-1` A == preimage of A by f. *) (* f @` A == image of A by f. *) (* A !=set0 := exists x, A x. *) (* is_singleton X <-> X contains only 1 element. *) (* is_fun f <-> for each a, f a contains only 1 element. *) (* is_total f <-> for each a, f a is non empty. *) (* is_totalfun f <-> conjunction of is_fun and is_total. *) (* xget x0 P == point x in P if it exists, x0 otherwise; *) (* P must be a set on a choiceType. *) (* fun_of_graph f0 f == function that maps x to an element of f x *) (* if there is one, to f0 x otherwise. *) (* *) (* --> Thanks to this basic set theory, we proved Zorn's Lemma, which states *) (* that any ordered set such that every totally ordered subset admits an *) (* upper bound has a maximal element. We also proved an analogous version *) (* for preorders, where maximal is replaced with premaximal: t is *) (* premaximal if whenever t < s we also have s < t. *) (******************************************************************************) (* -------------------------------------------------------------------- *) Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Declare Scope box_scope. Declare Scope quant_scope. (* Copy of the ssrbool shim to ensure compatibility with MathComp v1.8.0. *) Definition PredType : forall T pT, (pT -> pred T) -> predType T. exact PredType || exact mkPredType. Defined. Arguments PredType [T pT] toP. Local Notation predOfType T := (pred_of_simpl (@pred_of_argType T)). (* -------------------------------------------------------------------- *) Axiom functional_extensionality_dep : forall (A : Type) (B : A -> Type) (f g : forall x : A, B x), (forall x : A, f x = g x) -> f = g. Axiom propositional_extensionality : forall P Q : Prop, P <-> Q -> P = Q. Axiom constructive_indefinite_description : forall (A : Type) (P : A -> Prop), (exists x : A, P x) -> {x : A | P x}. Notation cid := constructive_indefinite_description. (* -------------------------------------------------------------------- *) Record mextentionality := { _ : forall (P Q : Prop), (P <-> Q) -> (P = Q); _ : forall {T U : Type} (f g : T -> U), (forall x, f x = g x) -> f = g; }. Fact extentionality : mextentionality. Proof. split. - exact: propositional_extensionality. - by move=> T U f g; apply: functional_extensionality_dep. Qed. Lemma propext (P Q : Prop) : (P <-> Q) -> (P = Q). Proof. by have [propext _] := extentionality; apply: propext. Qed. Lemma funext {T U : Type} (f g : T -> U) : (f =1 g) -> f = g. Proof. by case: extentionality=> _; apply. Qed. Lemma propeqE (P Q : Prop) : (P = Q) = (P <-> Q). Proof. by apply: propext; split=> [->|/propext]. Qed. Lemma funeqE {T U : Type} (f g : T -> U) : (f = g) = (f =1 g). Proof. by rewrite propeqE; split=> [->//|/funext]. Qed. Lemma funeq2E {T U V : Type} (f g : T -> U -> V) : (f = g) = (f =2 g). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite funeqE. Qed. Lemma funeq3E {T U V W : Type} (f g : T -> U -> V -> W) : (f = g) = (forall x y z, f x y z = g x y z). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> x y; rewrite funeqE. Qed. Lemma predeqE {T} (P Q : T -> Prop) : (P = Q) = (forall x, P x <-> Q x). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite propeqE. Qed. Lemma predeq2E {T U} (P Q : T -> U -> Prop) : (P = Q) = (forall x y, P x y <-> Q x y). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> ??; rewrite propeqE. Qed. Lemma predeq3E {T U V} (P Q : T -> U -> V -> Prop) : (P = Q) = (forall x y z, P x y z <-> Q x y z). Proof. by rewrite propeqE; split=> [->//|?]; rewrite funeq3E=> ???; rewrite propeqE. Qed. Lemma propT (P : Prop) : P -> P = True. Proof. by move=> p; rewrite propeqE; tauto. Qed. Lemma Prop_irrelevance (P : Prop) (x y : P) : x = y. Proof. by move: x (x) y => /propT-> [] []. Qed. Lemma choice X Y (P : X -> Y -> Prop) : (forall x, exists y, P x y) -> {f & forall x, P x (f x)}. Proof. by move=> /(_ _)/constructive_indefinite_description -/all_tag. Qed. (* Diaconescu Theorem *) Theorem EM P : P \/ ~ P. Proof. pose U val := fun Q : bool => Q = val \/ P. have Uex val : exists b, U val b by exists val; left. pose f val := projT1 (cid (Uex val)). pose Uf val : U val (f val) := projT2 (cid (Uex val)). have : f true <> f false \/ P. have [] := (Uf true, Uf false); rewrite /U. by move=> [->|?] [->|?] ; do ?[by right]; left. move=> [fTFN|]; [right=> p|by left]; apply: fTFN. have UTF : U true = U false by rewrite predeqE /U => b; split=> _; right. rewrite /f; move: (Uex true) (Uex false); rewrite UTF => p1 p2. by congr (projT1 (cid _)); apply: Prop_irrelevance. Qed. Lemma pselect (P : Prop): {P} + {~P}. Proof. have : exists b, if b then P else ~ P. by case: (EM P); [exists true|exists false]. by move=> /cid [[]]; [left|right]. Qed. Lemma pdegen (P : Prop): P = True \/ P = False. Proof. by have [p|Np] := pselect P; [left|right]; rewrite propeqE. Qed. Lemma lem (P : Prop): P \/ ~P. Proof. by case: (pselect P); tauto. Qed. (* -------------------------------------------------------------------- *) Lemma trueE : true = True :> Prop. Proof. by rewrite propeqE; split. Qed. Lemma falseE : false = False :> Prop. Proof. by rewrite propeqE; split. Qed. Lemma propF (P : Prop) : ~ P -> P = False. Proof. by move=> p; rewrite propeqE; tauto. Qed. Lemma eq_forall T (U V : T -> Prop) : (forall x : T, U x = V x) -> (forall x, U x) = (forall x, V x). Proof. by move=> e; rewrite propeqE; split=> ??; rewrite (e,=^~e). Qed. Lemma eq_exists T (U V : T -> Prop) : (forall x : T, U x = V x) -> (exists x, U x) = (exists x, V x). Proof. by move=> e; rewrite propeqE; split=> - [] x ?; exists x; rewrite (e,=^~e). Qed. Lemma reflect_eq (P : Prop) (b : bool) : reflect P b -> P = b. Proof. by rewrite propeqE; exact: rwP. Qed. Definition asbool (P : Prop) := if pselect P then true else false. Notation "`[< P >]" := (asbool P) : bool_scope. Lemma asboolE (P : Prop) : `[

] = P :> Prop. Proof. by rewrite propeqE /asbool; case: pselect; split. Qed. Lemma asboolP (P : Prop) : reflect P `[

]. Proof. by apply: (equivP idP); rewrite asboolE. Qed. Lemma asboolPn (P : Prop) : reflect (~ P) (~~ `[

]). Proof. by rewrite /asbool; case: pselect=> h; constructor. Qed. Lemma asboolW (P : Prop) : `[

] -> P. Proof. by case: asboolP. Qed. (* Shall this be a coercion ?*) Lemma asboolT (P : Prop) : P -> `[

]. Proof. by case: asboolP. Qed. Lemma asboolF (P : Prop) : ~ P -> `[

] = false. Proof. by apply/introF/asboolP. Qed. Lemma is_true_inj : injective is_true. Proof. by move=> [] []; rewrite ?(trueE, falseE) ?propeqE; tauto. Qed. (* -------------------------------------------------------------------- *) Lemma asbool_equiv_eq {P Q : Prop} : (P <-> Q) -> `[

] = `[]. Proof. by rewrite -propeqE => ->. Qed. Lemma asbool_equiv_eqP {P Q : Prop} QQ : reflect Q QQ -> (P <-> Q) -> `[

] = QQ. Proof. move=> Q_QQ [hPQ hQP]; apply/idP/Q_QQ=> [/asboolP//|]. by move=> hQ; apply/asboolP/hQP. Qed. Lemma asbool_equiv {P Q : Prop} : (P <-> Q) -> (`[

] <-> `[]). Proof. by move/asbool_equiv_eq->. Qed. Lemma asbool_eq_equiv {P Q : Prop} : `[

] = `[] -> (P <-> Q). Proof. by move=> eq; split=> /asboolP; rewrite (eq, =^~ eq) => /asboolP. Qed. (* -------------------------------------------------------------------- *) Lemma and_asboolP (P Q : Prop) : reflect (P /\ Q) (`[

] && `[]). Proof. apply: (iffP idP); first by case/andP=> /asboolP hP /asboolP hQ. by case=> /asboolP-> /asboolP->. Qed. Lemma or_asboolP (P Q : Prop) : reflect (P \/ Q) (`[

] || `[]). Proof. apply: (iffP idP); first by case/orP=> /asboolP; [left | right]. by case=> /asboolP-> //=; rewrite orbT. Qed. Lemma asbool_neg {P : Prop} : `[<~ P>] = ~~ `[

]. Proof. by apply/idP/asboolPn=> [/asboolP|/asboolT]. Qed. Lemma asbool_or {P Q : Prop} : `[

] = `[

] || `[]. Proof. exact: (asbool_equiv_eqP (or_asboolP _ _)). Qed. Lemma asbool_and {P Q : Prop} : `[

] = `[

] && `[]. Proof. exact: (asbool_equiv_eqP (and_asboolP _ _)). Qed. (* -------------------------------------------------------------------- *) Lemma imply_asboolP {P Q : Prop} : reflect (P -> Q) (`[

] ==> `[]). Proof. apply: (iffP implyP)=> [PQb /asboolP/PQb/asboolW //|]. by move=> PQ /asboolP/PQ/asboolT. Qed. Lemma asbool_imply {P Q : Prop} : `[

Q>] = `[

] ==> `[]. Proof. exact: (asbool_equiv_eqP imply_asboolP). Qed. Lemma imply_asboolPn (P Q : Prop) : reflect (P /\ ~ Q) (~~ `[

Q>]). Proof. apply: (iffP idP). by rewrite asbool_imply negb_imply -asbool_neg => /and_asboolP. by move/and_asboolP; rewrite asbool_neg -negb_imply asbool_imply. Qed. (* -------------------------------------------------------------------- *) Lemma forall_asboolP {T : Type} (P : T -> Prop) : reflect (forall x, `[

]) (`[]). Proof. apply: (iffP idP); first by move/asboolP=> Px x; apply/asboolP. by move=> Px; apply/asboolP=> x; apply/asboolP. Qed. Lemma exists_asboolP {T : Type} (P : T -> Prop) : reflect (exists x, `[

]) (`[]). Proof. apply: (iffP idP); first by case/asboolP=> x Px; exists x; apply/asboolP. by case=> x bPx; apply/asboolP; exists x; apply/asboolP. Qed. (* -------------------------------------------------------------------- *) Lemma contrap (Q P : Prop) : (Q -> P) -> ~ P -> ~ Q. Proof. move=> cb /asboolPn nb; apply/asboolPn. by apply: contra nb => /asboolP /cb /asboolP. Qed. Definition contrapNN := contra. Lemma contrapL (Q P : Prop) : (Q -> ~ P) -> P -> ~ Q. Proof. move=> cb /asboolP hb; apply/asboolPn. by apply: contraL hb => /asboolP /cb /asboolPn. Qed. Definition contrapTN := contrapL. Lemma contrapR (Q P : Prop) : (~ Q -> P) -> ~ P -> Q. Proof. move=> cb /asboolPn nb; apply/asboolP. by apply: contraR nb => /asboolP /cb /asboolP. Qed. Definition contrapNT := contrapR. Lemma contrapLR (Q P : Prop) : (~ Q -> ~ P) -> P -> Q. Proof. move=> cb /asboolP hb; apply/asboolP. by apply: contraLR hb => /asboolP /cb /asboolPn. Qed. Definition contrapTT := contrapLR. Lemma contrapT P : ~ ~ P -> P. Proof. by move/asboolPn=> nnb; apply/asboolP; apply: contraR nnb => /asboolPn /asboolP. Qed. Lemma wlog_neg P : (~ P -> P) -> P. Proof. by move=> ?; case: (pselect P). Qed. Lemma notT (P : Prop) : P = False -> ~ P. Proof. by move->. Qed. Lemma notTE (P : Prop) : (~ P) -> P = False. Proof. by case: (pdegen P)=> ->. Qed. Lemma notFE (P : Prop) : (~ P) = False -> P. Proof. move/notT; exact: contrapT. Qed. Lemma notK : involutive not. Proof. move=> P; case: (pdegen P)=> ->; last by apply: notTE; intuition. by rewrite [~ True]notTE //; case: (pdegen (~ False)) => // /notFE. Qed. Lemma not_inj : injective not. Proof. exact: can_inj notK. Qed. Lemma notLR P Q : (P = ~ Q) -> (~ P) = Q. Proof. exact: canLR notK. Qed. Lemma notRL P Q : (~ P) = Q -> P = ~ Q. Proof. exact: canRL notK. Qed. (* -------------------------------------------------------------------- *) (* assia : let's see if we need the simplpred machinery. In any case, we sould first try definitions + appropriate Arguments setting to see whether these can replace the canonical structures machinery. *) Definition predp T := T -> Prop. Identity Coercion fun_of_pred : predp >-> Funclass. Definition relp T := T -> predp T. Identity Coercion fun_of_rel : rel >-> Funclass. Notation xpredp0 := (fun _ => False). Notation xpredpT := (fun _ => True). Notation xpredpI := (fun (p1 p2 : predp _) x => p1 x /\ p2 x). Notation xpredpU := (fun (p1 p2 : predp _) x => p1 x \/ p2 x). Notation xpredpC := (fun (p : predp _) x => ~ p x). Notation xpredpD := (fun (p1 p2 : predp _) x => ~ p2 x /\ p1 x). Notation xpreimp := (fun f (p : predp _) x => p (f x)). Notation xrelpU := (fun (r1 r2 : relp _) x y => r1 x y \/ r2 x y). (* -------------------------------------------------------------------- *) Definition pred0p (T : Type) (P : predp T) : bool := `[

]. Prenex Implicits pred0p. Lemma pred0pP (T : Type) (P : predp T) : reflect (P =1 xpredp0) (pred0p P). Proof. by apply: (iffP (asboolP _)). Qed. (* -------------------------------------------------------------------- *) Module BoolQuant. Inductive box := Box & bool. Bind Scope box_scope with box. Delimit Scope box_scope with P. Definition idbox {T : Type} (B : box) := fun (x : T) => B. Definition unbox {T : Type} (B : T -> box) : bool := asbool (forall x : T, let: Box b := B x in b). Notation "F ^*" := (Box F) (at level 2). Notation "F ^~" := (~~ F) (at level 2). Section Definitions. Variable T : Type. Implicit Types (B : box) (x y : T). Definition quant0p Bp := pred0p (fun x : T => let: F^* := Bp x x in F). (* The first redundant argument protects the notation from Coq's K-term *) (* display kludge; the second protects it from simpl and /=. *) Definition ex B x y := B. (* Binding the predicate value rather than projecting it prevents spurious *) (* unfolding of the boolean connectives by unification. *) Definition all B x y := let: F^* := B in F^~^*. Definition all_in C B x y := let: F^* := B in (C ==> F)^~^*. Definition ex_in C B x y := let: F^* := B in (C && F)^*. End Definitions. Notation "`[ x | B ]" := (quant0p (fun x => B x)) (at level 0, x name). Notation "`[ x : T | B ]" := (quant0p (fun x : T => B x)) (at level 0, x name). Module Exports. Delimit Scope quant_scope with Q. (* Bogus, only used to declare scope. *) Bind Scope quant_scope with box. Notation ", F" := F^* (at level 200, format ", '/ ' F") : quant_scope. Notation "`[ 'forall' x B ]" := `[x | all B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' 'forall' x B ] ']'") : bool_scope. Notation "`[ 'forall' x : T B ]" := `[x : T | all B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'forall' ( x | C ) B ]" := `[x | all_in C B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'forall' ( x '/ ' | C ) ']' B ] ']'") : bool_scope. Notation "`[ 'forall' ( x : T | C ) B ]" := `[x : T | all_in C B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'forall' x 'in' A B ]" := `[x | all_in (x \in A) B] (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'forall' x '/ ' 'in' A ']' B ] ']'") : bool_scope. Notation "`[ 'forall' x : T 'in' A B ]" := `[x : T | all_in (x \in A) B] (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation ", 'forall' x B" := `[x | all B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' 'forall' x B") : quant_scope. Notation ", 'forall' x : T B" := `[x : T | all B]^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'forall' ( x | C ) B" := `[x | all_in C B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'forall' ( x '/ ' | C ) ']' B") : quant_scope. Notation ", 'forall' ( x : T | C ) B" := `[x : T | all_in C B]^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'forall' x 'in' A B" := `[x | all_in (x \in A) B]^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'forall' x '/ ' 'in' A ']' B") : bool_scope. Notation ", 'forall' x : T 'in' A B" := `[x : T | all_in (x \in A) B]^* (at level 200, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' x B ]" := `[x | ex B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' 'exists' x B ] ']'") : bool_scope. Notation "`[ 'exists' x : T B ]" := `[x : T | ex B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' ( x | C ) B ]" := `[x | ex_in C B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'exists' ( x '/ ' | C ) ']' B ] ']'") : bool_scope. Notation "`[ 'exists' ( x : T | C ) B ]" := `[x : T | ex_in C B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation "`[ 'exists' x 'in' A B ]" := `[x | ex_in (x \in A) B]^~ (at level 0, x at level 99, B at level 200, format "`[ '[hv' '[' 'exists' x '/ ' 'in' A ']' B ] ']'") : bool_scope. Notation "`[ 'exists' x : T 'in' A B ]" := `[x : T | ex_in (x \in A) B]^~ (at level 0, x at level 99, B at level 200, only parsing) : bool_scope. Notation ", 'exists' x B" := `[x | ex B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' 'exists' x B") : quant_scope. Notation ", 'exists' x : T B" := `[x : T | ex B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'exists' ( x | C ) B" := `[x | ex_in C B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'exists' ( x '/ ' | C ) ']' B") : quant_scope. Notation ", 'exists' ( x : T | C ) B" := `[x : T | ex_in C B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : quant_scope. Notation ", 'exists' x 'in' A B" := `[x | ex_in (x \in A) B]^~^* (at level 200, x at level 99, B at level 200, format ", '/ ' '[' 'exists' x '/ ' 'in' A ']' B") : bool_scope. Notation ", 'exists' x : T 'in' A B" := `[x : T | ex_in (x \in A) B]^~^* (at level 200, x at level 99, B at level 200, only parsing) : bool_scope. End Exports. End BoolQuant. Export BoolQuant.Exports. Open Scope quant_scope. (* -------------------------------------------------------------------- *) Section QuantifierCombinators. Variables (T : Type) (P : pred T) (PP : predp T). Hypothesis viewP : forall x, reflect (PP x) (P x). Lemma existsPP : reflect (exists x, PP x) `[exists x, P x]. Proof. apply: (iffP idP). move/asboolP; (* oops notation! *) apply: contrapR => nh x /=; apply: notTE. by apply: contrap nh => /viewP Px; exists x. case=> x PPx; apply/asboolP=> /(_ x) /notT /=; rewrite -/(not (~ P x)) notK. exact/viewP. Qed. Lemma forallPP : reflect (forall x, PP x) `[forall x, P x]. Proof. apply: (iffP idP). by move/asboolP=> h x; move/notT: (h x)=> /= /negP; rewrite negbK => /viewP. move=> h; apply/asboolP=> x; apply/notTE/negP; rewrite negbK; exact/viewP. Qed. End QuantifierCombinators. Section PredQuantifierCombinators. Variables (T : Type) (P : pred T). Lemma existsbP : reflect (exists x, P x) `[exists x, P x]. Proof. exact: existsPP (fun x => @idP (P x)). Qed. Lemma existsbE : `[exists x, P x] = `[]. Proof. apply/esym/is_true_inj; rewrite asboolE propeqE; apply: rwP; exact: existsbP. Qed. Lemma forallbP : reflect (forall x, P x) `[forall x, P x]. Proof. exact: forallPP (fun x => @idP (P x)). Qed. Lemma forallbE : `[forall x, P x] = `[]. Proof. apply/esym/is_true_inj; rewrite asboolE propeqE; apply: rwP; exact: forallbP. Qed. End PredQuantifierCombinators. (* -------------------------------------------------------------------- *) Lemma existsp_asboolP {T} {P : T -> Prop} : reflect (exists x : T, P x) `[exists x : T, `[

]]. Proof. exact: existsPP (fun x => @asboolP (P x)). Qed. Lemma forallp_asboolP {T} {P : T -> Prop} : reflect (forall x : T, P x) `[forall x : T, `[

]]. Proof. exact: forallPP (fun x => @asboolP (P x)). Qed. Lemma forallp_asboolPn {T} {P : T -> Prop} : reflect (forall x : T, ~ P x) (~~ `[]). Proof. apply: (iffP idP)=> [/asboolPn NP x Px|NP]. by apply/NP; exists x. by apply/asboolP=> -[x]; apply/NP. Qed. Lemma existsp_asboolPn {T} {P : T -> Prop} : reflect (exists x : T, ~ P x) (~~ `[]). Proof. apply: (iffP idP); last by case=> x NPx; apply/asboolPn=> /(_ x). move/asboolPn=> NP; apply/asboolP/negbNE/asboolPn=> h. by apply/NP=> x; apply/asboolP/negbNE/asboolPn=> NPx; apply/h; exists x. Qed. Lemma asbool_forallNb {T : Type} (P : pred T) : `[< forall x : T, ~~ (P x) >] = ~~ `[< exists x : T, P x >]. Proof. apply: (asbool_equiv_eqP forallp_asboolPn); by split=> h x; apply/negP/h. Qed. Lemma asbool_existsNb {T : Type} (P : pred T) : `[< exists x : T, ~~ (P x) >] = ~~ `[< forall x : T, P x >]. Proof. apply: (asbool_equiv_eqP existsp_asboolPn); by split=> -[x h]; exists x; apply/negP. Qed. Reserved Notation "[ 'set' x : T | P ]" (at level 0, x at level 99). Reserved Notation "[ 'set' x | P ]" (at level 0, x, P at level 99, format "[ 'set' x | P ]"). Reserved Notation "[ 'set' E | x 'in' A ]" (at level 0, E, x at level 99, format "[ '[hv' 'set' E '/ ' | x 'in' A ] ']'"). Reserved Notation "[ 'set' E | x 'in' A & y 'in' B ]" (at level 0, E, x at level 99, format "[ '[hv' 'set' E '/ ' | x 'in' A & y 'in' B ] ']'"). Reserved Notation "[ 'set' 'of' F ]" (at level 0, format "[ 'set' 'of' F ]"). Reserved Notation "[ 'set' a ]" (at level 0, a at level 99, format "[ 'set' a ]"). Reserved Notation "[ 'set' a : T ]" (at level 0, a at level 99, format "[ 'set' a : T ]"). Reserved Notation "A `|` B" (at level 52, left associativity). Reserved Notation "a |` A" (at level 52, left associativity). Reserved Notation "[ 'set' a1 ; a2 ; .. ; an ]" (at level 0, a1 at level 99, format "[ 'set' a1 ; a2 ; .. ; an ]"). Reserved Notation "A `&` B" (at level 48, left associativity). Reserved Notation "A `*` B" (at level 46, left associativity). Reserved Notation "A .`1" (at level 2, left associativity, format "A .`1"). Reserved Notation "A .`2" (at level 2, left associativity, format "A .`2"). Reserved Notation "~` A" (at level 35, right associativity). Reserved Notation "[ 'set' ~ a ]" (at level 0, format "[ 'set' ~ a ]"). Reserved Notation "A `\` B" (at level 50, left associativity). Reserved Notation "A `\ b" (at level 50, left associativity). (* Reserved Notation "A `+` B" (at level 54, left associativity). Reserved Notation "A +` B" (at level 54, left associativity). *) Reserved Notation "\bigcup_ ( i 'in' P ) F" (at level 41, F at level 41, i, P at level 50, format "'[' \bigcup_ ( i 'in' P ) '/ ' F ']'"). Reserved Notation "\bigcup_ ( i : T ) F" (at level 41, F at level 41, i at level 50, format "'[' \bigcup_ ( i : T ) '/ ' F ']'"). Reserved Notation "\bigcup_ i F" (at level 41, F at level 41, i at level 0, format "'[' \bigcup_ i '/ ' F ']'"). Reserved Notation "\bigcap_ ( i 'in' P ) F" (at level 41, F at level 41, i, P at level 50, format "'[' \bigcap_ ( i 'in' P ) '/ ' F ']'"). Reserved Notation "\bigcap_ ( i : T ) F" (at level 41, F at level 41, i at level 50, format "'[' \bigcap_ ( i : T ) '/ ' F ']'"). Reserved Notation "\bigcap_ i F" (at level 41, F at level 41, i at level 0, format "'[' \bigcap_ i '/ ' F ']'"). Reserved Notation "A `<=` B" (at level 70, no associativity). Reserved Notation "A `<=>` B" (at level 70, no associativity). Reserved Notation "f @^-1` A" (at level 24). Reserved Notation "f @` A" (at level 24). Reserved Notation "A !=set0" (at level 80). Definition set A := A -> Prop. Definition in_set T (P : set T) : pred T := [pred x | `[

]]. Canonical set_predType T := @PredType T (set T) (@in_set T). Lemma in_setE T (P : set T) x : x \in P = P x :> Prop. Proof. by rewrite propeqE; split => [] /asboolP. Qed. Declare Scope classical_set_scope. Bind Scope classical_set_scope with set. Local Open Scope classical_set_scope. Delimit Scope classical_set_scope with classic. Definition mkset {T} (A : T -> Prop) : set T := A. Notation "[ 'set' x : T | P ]" := (mkset (fun x : T => P)) : classical_set_scope. Notation "[ 'set' x | P ]" := [set x : _ | P] : classical_set_scope. Notation "[ 'set' E | x 'in' A ]" := [set y | exists2 x, A x & E = y] : classical_set_scope. Notation "[ 'set' E | x 'in' A & y 'in' B ]" := [set z | exists2 x, A x & exists2 y, B y & E = z] : classical_set_scope. Definition image {A B} (f : A -> B) (X : set A) : set B := [set f a | a in X]. Definition preimage {A B} (f : A -> B) (X : set B) : set A := [set a | X (f a)]. Arguments preimage A B f X / a. Definition setT {A} := [set _ : A | True]. Definition set0 {A} := [set _ : A | False]. Definition set1 {A} (x : A) := [set a : A | x = a]. Definition setI {A} (X Y : set A) := [set a | X a /\ Y a]. Definition setU {A} (X Y : set A) := [set a | X a \/ Y a]. Definition setV {A B} (X : set A) (Y : set B) := [set a : A + B | sum_rect _ X Y a]. Definition settt : set unit := setT. Definition nonempty {A} (X : set A) := exists x, X x. Definition setC {A} (X : set A) := [set a | ~ X a]. Definition setD {A} (X Y : set A) := [set a | X a /\ ~ Y a]. Definition setM {A B} (X : set A) (Y : set B) := [set x | X x.1 /\ Y x.2]. Definition fst_set {A B} (X : set (A * B)) := [set x | exists y, X (x, y)]. Definition snd_set {A B} (X : set (A * B)) := [set y | exists x, X (x, y)]. Notation "[ 'set' 'of' F ]" := [set F i | i in setT] : classical_set_scope. Notation "[ 'set' a ]" := (set1 a) : classical_set_scope. Notation "[ 'set' a : T ]" := [set (a : T)] : classical_set_scope. Notation "A `|` B" := (setU A B) : classical_set_scope. Notation "a |` A" := ([set a] `|` A) : classical_set_scope. Notation "[ 'set' a1 ; a2 ; .. ; an ]" := (setU .. (a1 |` [set a2]) .. [set an]) : classical_set_scope. Notation "A `&` B" := (setI A B) : classical_set_scope. Notation "A `*` B" := (setM A B) : classical_set_scope. Notation "A .`1" := (fst_set A) : classical_set_scope. Notation "A .`2" := (snd_set A) : classical_set_scope. Notation "~` A" := (setC A) : classical_set_scope. Notation "[ 'set' ~ a ]" := (~` [set a]) : classical_set_scope. Notation "A `\` B" := (setD A B) : classical_set_scope. Notation "A `\ a" := (A `\` [set a]) : classical_set_scope. Definition bigsetI A I (P : set I) (X : I -> set A) := [set a | forall i, P i -> X i a]. Definition bigsetU A I (P : set I) (X : I -> set A) := [set a | exists2 i, P i & X i a]. Notation "\bigcup_ ( i 'in' P ) F" := (bigsetU P (fun i => F)) : classical_set_scope. Notation "\bigcup_ ( i : T ) F" := (\bigcup_(i in @setT T) F) : classical_set_scope. Notation "\bigcup_ i F" := (\bigcup_(i : _) F) : classical_set_scope. Notation "\bigcap_ ( i 'in' P ) F" := (bigsetI P (fun i => F)) : classical_set_scope. Notation "\bigcap_ ( i : T ) F" := (\bigcap_(i in @setT T) F) : classical_set_scope. Notation "\bigcap_ i F" := (\bigcap_(i : _) F) : classical_set_scope. Definition subset {A} (X Y : set A) := forall a, X a -> Y a. Notation "A `<=` B" := (subset A B) : classical_set_scope. Notation "A `<=>` B" := ((A `<=` B) /\ (B `<=` A)) : classical_set_scope. Notation "f @^-1` A" := (preimage f A) : classical_set_scope. Notation "f @` A" := (image f A) : classical_set_scope. Notation "A !=set0" := (nonempty A) : classical_set_scope. Definition graph_sym {T T'} (A : set (T * T')) : set (T' * T) := [set xy | A (xy.2, xy.1)]. Definition graph_comp {T' T T''} (A : set (T * T')) (B : set (T' * T'')) : set (T * T'') := [set xz | exists2 y, A (xz.1, y) & B (y, xz.2)]. Lemma eqEsubset T (F G : set T) : F `<=` G -> G `<=` F -> F = G. Proof. by move=> H K; rewrite funeqE=> s; rewrite propeqE; split=> [/H|/K]. Qed. Lemma sub0set T (X : set T) : set0 `<=` X. Proof. by []. Qed. Lemma subset0 T (X : set T) : (X `<=` set0) = (X = set0). Proof. rewrite propeqE; split => [?|-> //]; exact/eqEsubset. Qed. Lemma set0P T (X : set T) : (X <> set0) <-> (X !=set0). Proof. split=> [X_neq0|[t tX] X_eq0]; last by rewrite X_eq0 in tX. apply: contrapT => /asboolPn/forallp_asboolPn X0. by apply/X_neq0/eqEsubset. Qed. Lemma imageP {A B} (f : A -> B) (X : set A) a : X a -> (f @` X) (f a). Proof. by exists a. Qed. Lemma sub_image_setI {A B} (f : A -> B) (X Y : set A) : f @` (X `&` Y) `<=` f @` X `&` f @` Y. Proof. by move=> b [x [Xa Ya <-]]; split; apply: imageP. Qed. Arguments sub_image_setI {A B f X Y} a _. Lemma nonempty_image {A B} (f : A -> B) (X : set A) : f @` X !=set0 -> X !=set0. Proof. by case=> b [a]; exists a. Qed. Lemma nonempty_preimage {A B} (f : A -> B) (X : set B) : f @^-1` X !=set0 -> X !=set0. Proof. by case=> [a ?]; exists (f a). Qed. Lemma preimage_image A B (f : A -> B) (X : set A) : X `<=` f@^-1` (f @` X). Proof. by move=> a Xa; exists a. Qed. Lemma image_preimage A B (f : A -> B) (X : set B) : f @` setT = setT -> f @` (f @^-1` X) = X. Proof. move=> fsurj; rewrite predeqE => x; split; first by move=> [?? <-]. move=> Xx; have : setT x by []; rewrite -fsurj => -[y _ fy_eqx]. by exists y => //; rewrite /preimage/mkset fy_eqx. Qed. Lemma preimage_setC A B (f : A -> B) (X : set B) : ~` (f @^-1` X) = f @^-1` (~` X). Proof. by rewrite predeqE => a; split=> nXfa ?; apply: nXfa. Qed. Lemma subset_empty {A} (X Y : set A) : X `<=` Y -> X !=set0 -> Y !=set0. Proof. by move=> sXY [x Xx]; exists x; apply: sXY. Qed. Lemma subset_trans {A} (Y X Z : set A) : X `<=` Y -> Y `<=` Z -> X `<=` Z. Proof. by move=> sXY sYZ ? ?; apply/sYZ/sXY. Qed. Lemma nonempty_preimage_setI {A B} (f : A -> B) (X Y : set B) : (f @^-1` (X `&` Y)) !=set0 <-> (f @^-1` X `&` f @^-1` Y) !=set0. Proof. by split; case=> x ?; exists x. Qed. Lemma subsetC {A} (X Y : set A) : X `<=` Y -> ~` Y `<=` ~` X. Proof. by move=> sXY ? nYa ?; apply/nYa/sXY. Qed. Lemma subsetU {A} (X Y Z : set A) : X `<=` Z -> Y `<=` Z -> X `|` Y `<=` Z. Proof. by move=> sXZ sYZ a; apply: or_ind; [apply: sXZ|apply: sYZ]. Qed. Lemma subUset T (X Y Z : set T) : (Y `|` Z `<=` X) = ((Y `<=` X) /\ (Z `<=` X)). Proof. rewrite propeqE; split => [|[YX ZX] x]; last by case; [exact: YX | exact: ZX]. by move=> sYZ_X; split=> x ?; apply sYZ_X; [left | right]. Qed. Lemma subsetI A (X Y Z : set A) : (X `<=` Y `&` Z) = ((X `<=` Y) /\ (X `<=` Z)). Proof. rewrite propeqE; split=> [H|[y z ??]]; split; by [move=> ?/H[]|apply y|apply z]. Qed. Lemma subIset {A} (X Y Z : set A) : X `<=` Z \/ Y `<=` Z -> X `&` Y `<=` Z. Proof. case => H a; by [move=> [/H] | move=> [_ /H]]. Qed. Lemma setD_eq0 A (X Y : set A) : (X `\` Y = set0) = (X `<=` Y). Proof. rewrite propeqE; split=> [XDY0 a|sXY]. by apply: contrapTT => nYa xA; rewrite -[False]/(set0 a) -XDY0. by rewrite predeqE => ?; split=> // - [?]; apply; apply: sXY. Qed. Lemma setDE {A} (X Y : set A) : X `\` Y = X `&` ~` Y. Proof. by []. Qed. Lemma setIid {A} (X : set A) : X `&` X = X. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma setIC {A} (X Y : set A) : X `&` Y = Y `&` X. Proof. by rewrite predeqE => ?; split=> [[]|[]]. Qed. Lemma setIT {A} (X : set A) : X `&` setT = X. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma setI0 {A} (X : set A) : X `&` set0 = set0. Proof. by rewrite predeqE => ?; split=> [[]|]. Qed. Lemma set0I A (Y : set A) : set0 `&` Y = set0. Proof. by rewrite setIC setI0. Qed. Lemma setIA {A} (X Y Z : set A) : X `&` (Y `&` Z) = X `&` Y `&` Z. Proof. by rewrite predeqE => ?; split=> [[? []]|[[]]]. Qed. Lemma setICA {A} (X Y Z : set A) : X `&` (Y `&` Z) = Y `&` (X `&` Z). Proof. by rewrite setIA [X `&` _]setIC -setIA. Qed. Lemma setIAC {A} (X Y Z : set A) : X `&` Y `&` Z = X `&` Z `&` Y. Proof. by rewrite setIC setICA setIA. Qed. Lemma setIACA {A} (X Y Z T : set A) : X `&` Y `&` (Z `&` T) = X `&` Z `&` (Y `&` T). Proof. by rewrite -setIA [Y `&` _]setICA setIA. Qed. Lemma setUA A : associative (@setU A). Proof. by move=> p q r; rewrite /setU /mkset predeqE => a; tauto. Qed. Lemma setUid A : idempotent (@setU A). Proof. move=> p; rewrite /setU predeqE /mkset => a; tauto. Qed. Lemma setUC A : commutative (@setU A). Proof. move=> p q; rewrite /setU predeqE /mkset => a; tauto. Qed. Lemma set0U T (X : set T) : set0 `|` X = X. Proof. by rewrite funeqE => t; rewrite propeqE; split; [case|right]. Qed. Lemma setU0 T (X : set T) : X `|` set0 = X. Proof. by rewrite funeqE => t; rewrite propeqE; split; [case|left]. Qed. Lemma setU_eq0 T (X Y : set T) : (X `|` Y = set0) = ((X = set0) /\ (Y = set0)). Proof. by rewrite -!subset0 subUset. Qed. Lemma setI_bigcapr A I (D : set I) (f : I -> set A) (X : set A) : X `&` \bigcap_(i in D) f i = \bigcap_(i in setV settt D) sum_rect (fun=> set A) (fun=> X) f i. Proof. rewrite predeqE => a; split; first by move=> [Xa IDfa] [[]|i]//= /IDfa. move=> IXDfa; split; first by apply: (IXDfa (inl tt)). by move=> i Di; apply: (IXDfa (inr i)). Qed. Lemma setI_bigcupl A I (D : set I) (f : I -> set A) (X : set A) : \bigcup_(i in D) f i `&` X = \bigcup_(i in D) (f i `&` X). Proof. rewrite predeqE => a; split => [[[i Di] fia] Xa|[i Di [fia Xa]]]. by exists i. by split=> //; exists i. Qed. Lemma setI_bigcupr A I (D : set I) (f : I -> set A) (X : set A) : X `&` \bigcup_(i in D) f i = \bigcup_(i in D) (X `&` f i). Proof. rewrite setIC setI_bigcupl; congr bigsetU. by rewrite funeqE => i; rewrite setIC. Qed. Lemma setU_bigcapl A I (D : set I) (f : I -> set A) (X : set A) : \bigcap_(i in D) f i `|` X = \bigcap_(i in D) (f i `|` X). Proof. rewrite predeqE => a; split => [|fI]. by move=> [fI|] i Di; [left; apply: fI|right]. by have [Xa|Xna] := asboolP (X a); [right |left => i /fI[]]. Qed. Lemma setU_bigcapr A I (D : set I) (f : I -> set A) (X : set A) : X `|` \bigcap_(i in D) f i = \bigcap_(i in D) (X `|` f i). Proof. rewrite setUC setU_bigcapl; congr bigsetI. by rewrite funeqE => i; rewrite setUC. Qed. Lemma bigcup_set1 {A I} (D : set I) (f : I -> set A) : \bigcup_(i in D) [set f i] = [set f i | i in D]. Proof. by []. Qed. Lemma bigcup_map {A I J} (D : set I) (h : I -> J) (f : J -> set A) : \bigcup_(i in D) f (h i) = \bigcup_(j in [set h i | i in D]) f j. Proof. rewrite predeqE => a; split=> [[i Di]|[_ [i Di <-]]] fhia; last by exists i. by exists (h i) => //; exists i. Qed. Lemma bigcup_bigcup {A I J} (DI : set I) (DJ : I -> set J) (f : J -> set A) : \bigcup_(j in \bigcup_(i in DI) DJ i) f j = \bigcup_(i in DI) \bigcup_(j in DJ i) f j. Proof. rewrite predeqE=> a; split => [[j [i Di Dij fja]]|[i Di [j Dij fja]]]. by exists i => //; exists j. by exists j => //; exists i. Qed. Lemma bigcap_bigcup {A I J} (DI : set I) (DJ : I -> set J) (f : J -> set A) : \bigcap_(j in \bigcup_(i in DI) DJ i) f j = \bigcap_(i in DI) \bigcap_(j in DJ i) f j. Proof. rewrite predeqE=> a; split=> [UUfa i Di j Dij|UUfa j [i Di Dij]]. by apply: UUfa; exists i. exact: UUfa Dij. Qed. Lemma bigcupM {I J A} (DI : set I) (DJ : set J) (f : I -> J -> set A) : \bigcup_(i in DI `*` DJ) f i.1 i.2 = \bigcup_(i in DI) \bigcup_(j in DJ) f i j. Proof. rewrite predeqE => i /=. split=> [[[a b] [/=Da Db] fabj]|[a Da [b Db fabi]]]; last by exists (a, b). by exists a => //; exists b => //. Qed. Definition is_singleton {A} (X : set A) := forall x y, X x -> X y -> x = y. Definition is_fun {A B} (f : A -> B -> Prop) := all (is_singleton \o f). Definition is_total {A B} (f : A -> B -> Prop) := all (nonempty \o f). Definition is_totalfun {A B} (f : A -> B -> Prop) := forall x, nonempty (f x) /\ is_singleton (f x). Record is_filter {T} (F : set (set T)) := IsFilter { filterT : F setT ; filterI : forall P Q : set T, F P -> F Q -> F (setI P Q) ; filterS : forall P Q : set T, P `<=` Q -> F P -> F Q; filter_not_empty : not (F (fun _ => False)) ; }. Definition xget {T} x0 (P : set T) : T := if pselect (exists x : T, `[

]) isn't left exP then x0 else projT1 (cid exP). Unset Auto Template Polymorphism. CoInductive xget_spec {T} x0 (P : set T) : T -> Prop -> Type := | XGetSome x of x = xget x0 P & P x : xget_spec x0 P x True | XGetNone of (forall x, ~ P x) : xget_spec x0 P x0 False. Lemma xgetP {T} x0 (P : set T) : xget_spec x0 P (xget x0 P) (P (xget x0 P)). Proof. move: (erefl (xget x0 P)); set y := {2}(xget x0 P). rewrite /xget; case: pselect => /= [?|neqP _]. by case: cid => x /= /asboolP Px; rewrite [P x]propT //; constructor. suff NP x : ~ P x by rewrite [P x0]propF //; constructor. by apply: contrap neqP => Px; exists x; apply/asboolP. Qed. Lemma xgetPex {T} x0 (P : set T) : (exists x, P x) -> P (xget x0 P). Proof. by case: xgetP=> // NP [x /NP]. Qed. Lemma xgetI {T} x0 (P : set T) (x : T): P x -> P (xget x0 P). Proof. by move=> Px; apply: xgetPex; exists x. Qed. Lemma xget_prop {T : nonPropType} x0 (P : set T) (x : T) : P x -> is_singleton P -> xget x0 P = x. Proof. by move=> Px /(_ _ _ (xgetI x0 Px) Px). Qed. Lemma xget_unique {T} x0 (P : set T) (x : T) : P x -> (forall y, P y -> y = x) -> xget x0 P = x. Proof. by move=> /xget_prop gPx eqx; apply: gPx=> y z /eqx-> /eqx. Qed. Lemma xgetPN {T} x0 (P : set T) : (forall x, ~ P x) -> xget x0 P = x0. Proof. by case: xgetP => // x _ Px /(_ x). Qed. Definition fun_of_graph {A} {B} (f0 : A -> B) (f : A -> B -> Prop) := fun x => xget (f0 x) (f x). Lemma fun_of_graphP {A} {B } (f : A -> B -> Prop) (f0 : A -> B) a : nonempty (f a) -> f a (fun_of_graph f0 f a). Proof. by move=> [b fab]; rewrite /fun_of_graph; apply: xgetI fab. Qed. Lemma fun_of_graph_uniq {A} {B } (f : A -> B -> Prop) (f0 : A -> B) a : is_singleton (f a) -> forall b, f a b -> fun_of_graph f0 f a = b. Proof. by move=> fa_prop b /xget_prop xgeteq; rewrite /fun_of_graph xgeteq. Qed. Definition total_on T (A : set T) (R : T -> T -> Prop) := forall s t, A s -> A t -> R s t \/ R t s. Section ZL. Variable (T : Type) (t0 : T) (R : T -> T -> Prop). Hypothesis (Rrefl : forall t, R t t). Hypothesis (Rtrans : forall r s t, R r s -> R s t -> R r t). Hypothesis (Rantisym : forall s t, R s t -> R t s -> s = t). Hypothesis (tot_lub : forall A : set T, total_on A R -> exists t, (forall s, A s -> R s t) /\ forall r, (forall s, A s -> R s r) -> R t r). Hypothesis (Rsucc : forall s, exists t, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t). Notation get := (xget t0). Notation getPex := (xgetPex t0). Let lub := fun A : {A : set T | total_on A R} => get (fun t : T => (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r). Let succ := fun s => get (fun t : T => R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t). Inductive tower : set T := | Lub : forall A, sval A `<=` tower -> tower (lub A) | Succ : forall t, tower t -> tower (succ t). Lemma ZL' : False. Proof. have lub_ub (A : {A : set T | total_on A R}) : forall s, sval A s -> R s (lub A). suff /getPex [] : exists t : T, (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r by []. by apply: tot_lub; apply: (svalP A). have lub_lub (A : {A : set T | total_on A R}) : forall t, (forall s, sval A s -> R s t) -> R (lub A) t. suff /getPex [] : exists t : T, (forall s, sval A s -> R s t) /\ forall r, (forall s, sval A s -> R s r) -> R t r by []. by apply: tot_lub; apply: (svalP A). have RS s : R s (succ s) /\ s <> succ s. by have /getPex [? []] : exists t : T, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t by apply: Rsucc. have succS s : forall t, R s t -> R t (succ s) -> t = s \/ t = succ s. by have /getPex [? []] : exists t : T, R s t /\ s <> t /\ forall r, R s r -> R r t -> r = s \/ r = t by apply: Rsucc. suff Twtot : total_on tower R. have [R_S] := RS (lub (exist _ tower Twtot)); apply. by apply/Rantisym => //; apply/lub_ub/Succ/Lub. move=> s t Tws; elim: Tws t => {s} [A sATw ihA|s Tws ihs] t Twt. case: (pselect (forall s, sval A s -> R s t)). by move=> ?; left; apply: lub_lub. move/asboolP; rewrite asbool_neg => /existsp_asboolPn [s /asboolP]. rewrite asbool_neg => /imply_asboolPn [As nRst]; right. by have /lub_ub := As; apply: Rtrans; have [] := ihA _ As _ Twt. suff /(_ _ Twt) [Rts|RSst] : forall r, tower r -> R r s \/ R (succ s) r. by right; apply: Rtrans Rts _; have [] := RS s. by left. move=> r; elim=> {r} [A sATw ihA|r Twr ihr]. case: (pselect (forall r, sval A r -> R r s)). by move=> ?; left; apply: lub_lub. move/asboolP; rewrite asbool_neg => /existsp_asboolPn [r /asboolP]. rewrite asbool_neg => /imply_asboolPn [Ar nRrs]; right. by have /lub_ub := Ar; apply: Rtrans; have /ihA [] := Ar. have [Rrs|RSsr] := ihr; last by right; apply: Rtrans RSsr _; have [] := RS r. have : tower (succ r) by apply: Succ. move=> /ihs [RsSr|]; last by left. by have [->| ->] := succS _ _ Rrs RsSr; [right|left]; apply: Rrefl. Qed. End ZL. Lemma exist_congr T (P : T -> Prop) (s t : T) (p : P s) (q : P t) : s = t -> exist P s p = exist P t q. Proof. by move=> st; case: _ / st in q *; apply/congr1/Prop_irrelevance. Qed. Lemma Zorn T (R : T -> T -> Prop) : (forall t, R t t) -> (forall r s t, R r s -> R s t -> R r t) -> (forall s t, R s t -> R t s -> s = t) -> (forall A : set T, total_on A R -> exists t, forall s, A s -> R s t) -> exists t, forall s, R t s -> s = t. Proof. move=> Rrefl Rtrans Rantisym Rtot_max. set totR := ({A : set T | total_on A R}). set R' := fun A B : totR => sval A `<=` sval B. have R'refl A : R' A A by []. have R'trans A B C : R' A B -> R' B C -> R' A C by apply: subset_trans. have R'antisym A B : R' A B -> R' B A -> A = B. rewrite /R'; case: A; case: B => /= B totB A totA sAB sBA. by apply: exist_congr; rewrite predeqE=> ?; split=> [/sAB|/sBA]. have R'tot_lub A : total_on A R' -> exists t, (forall s, A s -> R' s t) /\ forall r, (forall s, A s -> R' s r) -> R' t r. move=> Atot. have AUtot : total_on (\bigcup_(B in A) (sval B)) R. move=> s t [B AB Bs] [C AC Ct]. have [/(_ _ Bs) Cs|/(_ _ Ct) Bt] := Atot _ _ AB AC. by have /(_ _ _ Cs Ct) := svalP C. by have /(_ _ _ Bs Bt) := svalP B. exists (exist _ (\bigcup_(B in A) sval B) AUtot); split. by move=> B ???; exists B. by move=> B Bub ? /= [? /Bub]; apply. apply: contrapT => nomax. have {}nomax t : exists s, R t s /\ s <> t. have /asboolP := nomax; rewrite asbool_neg => /forallp_asboolPn /(_ t). move=> /asboolP; rewrite asbool_neg => /existsp_asboolPn [s]. by move=> /asboolP; rewrite asbool_neg => /imply_asboolPn []; exists s. have tot0 : total_on set0 R by []. apply: (ZL' (exist _ set0 tot0)) R'tot_lub _ => // A. have /Rtot_max [t tub] := svalP A; have [s [Rts snet]] := nomax t. have Astot : total_on (sval A `|` [set s]) R. move=> u v [Au|<-]; last first. by move=> [/tub Rvt| ->]; right=> //; apply: Rtrans Rts. move=> [Av|<-]; [apply: (svalP A)|left] => //. by apply: Rtrans Rts; apply: tub. exists (exist _ (sval A `|` [set s]) Astot); split; first by move=> ??; left. split=> [AeAs|[B Btot] sAB sBAs]. case: (pselect (sval A s)); first by move=> /tub Rst; apply/snet/Rantisym. by rewrite AeAs /=; apply; right. case: (pselect (B s)) => [Bs|nBs]. by right; apply: exist_congr; rewrite predeqE => r; split=> [/sBAs|[/sAB| <-]]. left; case: A tub Astot sBAs sAB => A Atot /= tub Astot sBAs sAB. apply: exist_congr; rewrite predeqE => r; split=> [Br|/sAB] //. by have /sBAs [|ser] // := Br; rewrite -ser in Br. Qed. Definition premaximal T (R : T -> T -> Prop) (t : T) := forall s, R t s -> R s t. Lemma ZL_preorder T (t0 : T) (R : T -> T -> Prop) : (forall t, R t t) -> (forall r s t, R r s -> R s t -> R r t) -> (forall A : set T, total_on A R -> exists t, forall s, A s -> R s t) -> exists t, premaximal R t. Proof. move=> Rrefl Rtrans tot_max. set eqR := fun s t => R s t /\ R t s; set ceqR := fun s => [set t | eqR s t]. have eqR_trans r s t : eqR r s -> eqR s t -> eqR r t. by move=> [Rrs Rsr] [Rst Rts]; split; [apply: Rtrans Rst|apply: Rtrans Rsr]. have ceqR_uniq s t : eqR s t -> ceqR s = ceqR t. by rewrite predeqE => - [Rst Rts] r; split=> [[Rr rR] | [Rr rR]]; split; try exact: Rtrans Rr; exact: Rtrans rR _. set ceqRs := ceqR @` setT; set quotR := sig ceqRs. have ceqRP t : ceqRs (ceqR t) by exists t. set lift := fun t => exist _ (ceqR t) (ceqRP t). have lift_surj (A : quotR) : exists t : T, lift t = A. case: A => A [t Tt ctA]; exists t; rewrite /lift; case : _ / ctA. exact/congr1/Prop_irrelevance. have lift_inj s t : eqR s t -> lift s = lift t. by move=> eqRst; apply/exist_congr/ceqR_uniq. have lift_eqR s t : lift s = lift t -> eqR s t. move=> cst; have ceqst : ceqR s = ceqR t by have := congr1 sval cst. by rewrite [_ s]ceqst; split; apply: Rrefl. set repr := fun A : quotR => xget t0 [set t : T | lift t = A]. have repr_liftE t : eqR t (repr (lift t)) by apply: lift_eqR; have -> := xgetPex t0 (lift_surj (lift t)). set R' := fun A B : quotR => R (repr A) (repr B). have R'refl A : R' A A by apply: Rrefl. have R'trans A B C : R' A B -> R' B C -> R' A C by apply: Rtrans. have R'antisym A B : R' A B -> R' B A -> A = B. move=> RAB RBA; have [t tA] := lift_surj A; have [s sB] := lift_surj B. rewrite -tA -sB; apply: lift_inj; apply (eqR_trans _ _ _ (repr_liftE t)). have eAB : eqR (repr A) (repr B) by []. rewrite tA; apply: eqR_trans eAB _; rewrite -sB. by have [] := repr_liftE s. have [A Atot|A Amax] := Zorn R'refl R'trans R'antisym. have /tot_max [t tmax] : total_on [set repr B | B in A] R. by move=> ?? [B AB <-] [C AC <-]; apply: Atot. exists (lift t) => B AB; have [Rt _] := repr_liftE t. by apply: Rtrans Rt; apply: tmax; exists B. exists (repr A) => t RAt. have /Amax <- : R' A (lift t). by have [Rt _] := repr_liftE t; apply: Rtrans Rt. by have [] := repr_liftE t. Qed. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/stage10.v000066400000000000000000000165131521677141400252040ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool ZArith QArith Qcanon. From HB Require Import structures. Require Import classical. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope classical_set_scope. Local Open Scope hb_scope. Module Stage10. HB.mixin Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section AddAGTheory. Variable A : AddAG.type. Implicit Type (x : A). Lemma addr0 : right_id (@zero A) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrK : right_loop (@opp A) (@add A). Proof. by move=> x y; rewrite -addrA subrr addr0. Qed. Lemma addKr : left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA addNr add0r. Qed. Lemma addrNK : rev_right_loop (@opp A) (@add A). Proof. by move=> y x; rewrite -addrA addNr addr0. Qed. Lemma addNKr : rev_left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA subrr add0r. Qed. Lemma addrAC : right_commutative (@add A). Proof. by move=> x y z; rewrite -!addrA [y + z]addrC. Qed. Lemma addrCA : left_commutative (@add A). Proof. by move=> x y z; rewrite !addrA [x + y]addrC. Qed. Lemma addrACA : interchange (@add A) add. Proof. by move=> x y z t; rewrite !addrA [x + y + z]addrAC. Qed. Lemma opprK : involutive (@opp A). Proof. by move=> x; apply: (can_inj (addrK (- x))); rewrite addNr addrN. Qed. Lemma opprD x y : - (x + y) = - x - y. Proof. apply: (can_inj (addKr (x + y))). by rewrite subrr addrACA !subrr addr0. Qed. Lemma opprB x y : - (x - y) = y - x. Proof. by rewrite opprD opprK addrC. Qed. End AddAGTheory. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddAG_of_TYPE := AddAG_of_TYPE.Build A _ _ _ addrA addrC add0r addNr. HB.instance Definition to_Ring_of_AddAG := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. HB.mixin Record Topological T := { open : (T -> Prop) -> Prop; open_setT : open setT; open_bigcup : forall {I} (D : set I) (F : I -> set T), (forall i, D i -> open (F i)) -> open (\bigcup_(i in D) F i); open_setI : forall X Y : set T, open X -> open Y -> open (setI X Y); }. HB.structure Definition TopologicalSpace := { A of Topological A }. #[export] Hint Extern 0 (open setT) => now apply: open_setT : core. HB.factory Record TopologicalBase T := { open_base : set (set T); open_base_covers : setT `<=` \bigcup_(X in open_base) X; open_base_cup : forall X Y : set T, open_base X -> open_base Y -> forall z, (X `&` Y) z -> exists2 Z, open_base Z & Z z /\ Z `<=` X `&` Y }. HB.builders Context T (a : TopologicalBase T). Definition open_of : (T -> Prop) -> Prop := [set A | exists2 D, D `<=` open_base & A = \bigcup_(X in D) X]. Lemma open_of_setT : open_of setT. Proof. exists open_base; rewrite // predeqE => x; split=> // _. by apply: open_base_covers. Qed. Lemma open_of_bigcup {I} (D : set I) (F : I -> set T) : (forall i, D i -> open_of (F i)) -> open_of (\bigcup_(i in D) F i). Proof. Admitted. Lemma open_of_cap X Y : open_of X -> open_of Y -> open_of (X `&` Y). Proof. Admitted. HB.instance Definition to_Topological := Topological.Build T _ open_of_setT (@open_of_bigcup) open_of_cap. HB.end. Section ProductTopology. Variables (T1 T2 : TopologicalSpace.type). Definition prod_open_base := [set A | exists (A1 : set T1) (A2 : set T2), open A1 /\ open A2 /\ A = setM A1 A2]. Lemma prod_open_base_covers : setT `<=` \bigcup_(X in prod_open_base) X. Proof. move=> X _; exists setT => //; exists setT, setT; do ?split. - exact: open_setT. - exact: open_setT. - by rewrite predeqE. Qed. Lemma prod_open_base_setU X Y : prod_open_base X -> prod_open_base Y -> forall z, (X `&` Y) z -> exists2 Z, prod_open_base Z & Z z /\ Z `<=` X `&` Y. Proof. move=> [A1 [A2 [A1open [A2open ->]]]] [B1 [B2 [B1open [B2open ->]]]]. move=> [z1 z2] [[/=Az1 Az2] [/= Bz1 Bz2]]. exists ((A1 `&` B1) `*` (A2 `&` B2)). by eexists _, _; do ?[split; last first]; apply: open_setI. by split => // [[x1 x2] [[/=Ax1 Bx1] [/=Ax2 Bx2]]]. Qed. HB.instance Definition prod_topology := TopologicalBase.Build (T1 * T2)%type _ prod_open_base_covers prod_open_base_setU. End ProductTopology. Definition continuous {T T' : TopologicalSpace.type} (f : T -> T') := forall B : set T', open B -> open (f@^-1` B). Definition continuous2 {T T' T'': TopologicalSpace.type} (f : T -> T' -> T'') := continuous (fun xy => f xy.1 xy.2). HB.mixin Record JoinTAddAG T & AddAG_of_TYPE T & Topological T := { add_continuous : continuous2 (add : T -> T -> T); opp_continuous : continuous (opp : T -> T) }. HB.structure Definition TAddAG := { A of Topological A & AddAG_of_TYPE A & JoinTAddAG A }. (* Instance *) HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrK addr0. Qed. Import Qcanon. Search _ Qc "plus" "opp". Lemma Qcplus_opp_l q : - q + q = 0. Proof. by rewrite Qcplus_comm Qcplus_opp_r. Qed. HB.instance Definition Qc_ring_axioms := Ring_of_TYPE.Build Qc 0%Qc 1%Qc Qcplus Qcopp Qcmult Qcplus_assoc Qcplus_comm Qcplus_0_l Qcplus_opp_l Qcmult_assoc Qcmult_1_l Qcmult_1_r Qcmult_plus_distr_l Qcmult_plus_distr_r. Obligation Tactic := idtac. Definition Qcopen_base : set (set Qc) := [set A | exists a b : Qc, forall z, A z <-> a < z /\ z < b]. Program Definition QcTopological := TopologicalBase.Build Qc Qcopen_base _ _. Next Obligation. move=> x _; exists [set y | x - 1 < y < x + 1]. by exists (x - 1), (x + 1). split; rewrite Qclt_minus_iff. by rewrite -[_ + _]/(x - (x - 1))%G opprB addrCA subrr. by rewrite -[_ + _]/(x + 1 - x)%G addrAC subrr. Qed. Next Obligation. move=> X Y [aX [bX Xeq]] [aY [bY Yeq]] z [/Xeq [aXz zbX] /Yeq [aYz zbY]]. Admitted. HB.instance Definition _ : TopologicalBase Qc := QcTopological. Program Definition QcJoinTAddAG := JoinTAddAG.Build Qc _ _. Next Obligation. Admitted. Next Obligation. Admitted. HB.instance Definition _ : JoinTAddAG Qc := QcJoinTAddAG. End Stage10. math-comp-hierarchy-builder-4d8a939/examples_stdlib/demo2/stage11.v000066400000000000000000000300611521677141400251770ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool ZArith QArith Qcanon. From HB Require Import structures. Require Import classical. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope classical_set_scope. Local Open Scope hb_scope. Module Stage11. HB.mixin Record AddAG_of_TYPE A := { zero : A; add : A -> A -> A; opp : A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; }. HB.structure Definition AddAG := { A of AddAG_of_TYPE A }. (* TODO: command hb.module_export which creates a module, exports it immediatly and remembers that it should be added to the final Theory module created at file closure *) Notation "0" := zero : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. (* Theory *) Section AddAGTheory. Variable A : AddAG.type. Implicit Type (x : A). Lemma addr0 : right_id (@zero A) add. Proof. by move=> x; rewrite addrC add0r. Qed. Lemma addrN : right_inverse (@zero A) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrK : right_loop (@opp A) (@add A). Proof. by move=> x y; rewrite -addrA subrr addr0. Qed. Lemma addKr : left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA addNr add0r. Qed. Lemma addrNK : rev_right_loop (@opp A) (@add A). Proof. by move=> y x; rewrite -addrA addNr addr0. Qed. Lemma addNKr : rev_left_loop (@opp A) (@add A). Proof. by move=> x y; rewrite addrA subrr add0r. Qed. Lemma addrAC : right_commutative (@add A). Proof. by move=> x y z; rewrite -!addrA [y + z]addrC. Qed. Lemma addrCA : left_commutative (@add A). Proof. by move=> x y z; rewrite !addrA [x + y]addrC. Qed. Lemma addrACA : interchange (@add A) add. Proof. by move=> x y z t; rewrite !addrA [x + y + z]addrAC. Qed. Lemma opprK : involutive (@opp A). Proof. by move=> x; apply: (can_inj (addrK (- x))); rewrite addNr addrN. Qed. Lemma opprD x y : - (x + y) = - x - y. Proof. apply: (can_inj (addKr (x + y))). by rewrite subrr addrACA !subrr addr0. Qed. Lemma opprB x y : - (x - y) = y - x. Proof. by rewrite opprD opprK addrC. Qed. End AddAGTheory. HB.mixin Record Ring_of_AddAG A & AddAG A := { one : A; mul : A -> A -> A; mulrA : associative mul; mulr1 : left_id one mul; mul1r : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddAG := AddAG_of_TYPE.Build A _ _ _ addrA addrC add0r addNr. HB.instance Definition to_Ring := Ring_of_AddAG.Build A _ _ mulrA mul1r mulr1 mulrDl mulrDr. HB.end. HB.structure Definition Ring := { A of Ring_of_TYPE A }. Notation "1" := one : hb_scope. Infix "*" := (@mul _) : hb_scope. HB.mixin Record Topological T := { open : (T -> Prop) -> Prop; open_setT : open setT; open_bigcup : forall {I} (D : set I) (F : I -> set T), (forall i, D i -> open (F i)) -> open (\bigcup_(i in D) F i); open_setI : forall X Y : set T, open X -> open Y -> open (setI X Y); }. HB.structure Definition TopologicalSpace := { A of Topological A }. #[export] Hint Extern 0 (open setT) => now apply: open_setT : core. HB.factory Record TopologicalBase T := { open_base : set (set T); open_base_covers : setT `<=` \bigcup_(X in open_base) X; open_base_cup : forall X Y : set T, open_base X -> open_base Y -> forall z, (X `&` Y) z -> exists2 Z, open_base Z & Z z /\ Z `<=` X `&` Y }. HB.builders Context T (a : TopologicalBase T). Definition open_of := [set A | exists2 D, D `<=` open_base & A = \bigcup_(X in D) X]. Lemma open_of_setT : open_of setT. Proof. exists open_base; rewrite // predeqE => x; split=> // _. by apply: open_base_covers. Qed. Lemma open_of_bigcup {I} (D : set I) (F : I -> set T) : (forall i, D i -> open_of (F i)) -> open_of (\bigcup_(i in D) F i). Proof. Admitted. Lemma open_of_cap X Y : open_of X -> open_of Y -> open_of (X `&` Y). Proof. Admitted. HB.instance Definition to_Topological := Topological.Build T _ open_of_setT (@open_of_bigcup) open_of_cap. HB.end. Section ProductTopology. Variables (T1 T2 : TopologicalSpace.type). Definition prod_open_base := [set A | exists (A1 : set T1) (A2 : set T2), open A1 /\ open A2 /\ A = setM A1 A2]. Lemma prod_open_base_covers : setT `<=` \bigcup_(X in prod_open_base) X. Proof. move=> X _; exists setT => //; exists setT, setT; do ?split. - exact: open_setT. - exact: open_setT. - by rewrite predeqE. Qed. Lemma prod_open_base_setU X Y : prod_open_base X -> prod_open_base Y -> forall z, (X `&` Y) z -> exists2 Z, prod_open_base Z & Z z /\ Z `<=` X `&` Y. Proof. move=> [A1 [A2 [A1open [A2open ->]]]] [B1 [B2 [B1open [B2open ->]]]]. move=> [z1 z2] [[/=Az1 Az2] [/= Bz1 Bz2]]. exists ((A1 `&` B1) `*` (A2 `&` B2)). by eexists _, _; do ?[split; last first]; apply: open_setI. by split => // [[x1 x2] [[/=Ax1 Bx1] [/=Ax2 Bx2]]]. Qed. HB.instance Definition prod_topology := TopologicalBase.Build (T1 * T2)%type _ prod_open_base_covers prod_open_base_setU. End ProductTopology. (* TODO: infer continuous as a morphism of Topology *) Definition continuous {T T' : TopologicalSpace.type} (f : T -> T') := forall B : set T', open B -> open (f@^-1` B). Definition continuous2 {T T' T'': TopologicalSpace.type} (f : T -> T' -> T'') := continuous (fun xy => f xy.1 xy.2). HB.mixin Record JoinTAddAG_wo_Uniform T & AddAG_of_TYPE T & Topological T := { add_continuous : continuous2 (add : T -> T -> T); opp_continuous : continuous (opp : T -> T) }. HB.structure Definition TAddAG_wo_Uniform := { A of Topological A & AddAG_of_TYPE A & JoinTAddAG_wo_Uniform A }. HB.mixin Record Uniform_wo_Topology U := { entourage : set (set (U * U)) ; filter_entourage : is_filter entourage ; entourage_sub : forall A, entourage A -> [set xy | xy.1 = xy.2] `<=` A; entourage_sym : forall A, entourage A -> entourage (graph_sym A) ; entourage_split : forall A, entourage A -> exists2 B, entourage B & graph_comp B B `<=` A ; }. HB.structure Definition UniformSpace_wo_Topology := { A of Uniform_wo_Topology A }. (* TODO: have a command hb.typealias which register "typealias factories" which turn a typealias into factories *) Definition uniform T : Type := T. Section Uniform_Topology. Variable U : UniformSpace_wo_Topology.type. Definition uniform_open : set (set (uniform U)). Admitted. Lemma uniform_open_setT : uniform_open setT. Admitted. Lemma uniform_open_bigcup : forall {I} (D : set I) (F : I -> set U), (forall i, D i -> uniform_open (F i)) -> uniform_open (\bigcup_(i in D) F i). Admitted. Lemma uniform_open_setI : forall X Y : set U, uniform_open X -> uniform_open Y -> uniform_open (setI X Y). Admitted. HB.instance Definition uniform_topology := Topological.Build (uniform U) _ uniform_open_setT (@uniform_open_bigcup) uniform_open_setI. End Uniform_Topology. HB.mixin Record Join_Uniform_Topology U & Topological U & Uniform_wo_Topology U := { openE : open = (uniform_open _ : set (set (uniform U))) }. (* TODO: this factory should be replaced by type alias uniform *) HB.factory Record Uniform_Topology U & Uniform_wo_Topology U := { }. HB.builders Context U (f : Uniform_Topology U). HB.instance Definition to_Topological : Topological U := (uniform_topology _). HB.end. HB.structure Definition UniformSpace := { A of Uniform_Topology A (* should be replaced by typealias uniform *) & Uniform_wo_Topology A }. (* TODO: should be ommited *) (* TODO: this is another typealias *) Definition tAddAG (T : Type) := T. Section TAddAGUniform. Variable T : TAddAG_wo_Uniform.type. Notation TT := (tAddAG T). Definition TAddAG_entourage : set (set (TT * TT)). Admitted. Lemma filter_TAddAG_entourage : is_filter TAddAG_entourage. Admitted. Lemma TAddAG_entourage_sub : forall A, TAddAG_entourage A -> [set xy | xy.1 = xy.2] `<=` A. Admitted. Lemma TAddAG_entourage_sym : forall A, TAddAG_entourage A -> TAddAG_entourage (graph_sym A). Admitted. Lemma TAddAG_entourage_split : forall A, TAddAG_entourage A -> exists2 B, TAddAG_entourage B & graph_comp B B `<=` A. Admitted. HB.instance Definition TAddAG_uniform := Uniform_wo_Topology.Build (tAddAG T) _ filter_TAddAG_entourage TAddAG_entourage_sub TAddAG_entourage_sym TAddAG_entourage_split. Lemma TAddAG_uniform_topologyE : open = (uniform_open _ : set (set (uniform TT))). Admitted. HB.instance Definition TAddAG_Join_Uniform_Topology := Join_Uniform_Topology.Build TT TAddAG_uniform_topologyE. Lemma TAddAG_entourageE : entourage = (TAddAG_entourage : set (set (TT * TT))). Admitted. End TAddAGUniform. HB.structure Definition Uniform_TAddAG_unjoined := { A of TAddAG_wo_Uniform A & Uniform_wo_Topology A }. (* should be created automatically *) HB.mixin Record Join_TAddAG_Uniform T & Uniform_TAddAG_unjoined T := { entourageE : entourage = (TAddAG_entourage _ : set (set (tAddAG T * tAddAG T))) }. (* TODO: should be subsumed by the type alias TAddAG *) HB.factory Record TAddAG_Uniform U & TAddAG_wo_Uniform U := { }. HB.builders Context U (a : TAddAG_Uniform U). HB.instance Definition to_Uniform_wo_Topology : Uniform_wo_Topology U := TAddAG_uniform _. HB.instance Definition to_Join_Uniform_Topology : Join_Uniform_Topology U := TAddAG_Join_Uniform_Topology _. HB.instance Definition to_Join_TAddAG_Uniform : Join_TAddAG_Uniform U := Join_TAddAG_Uniform.Build U (TAddAG_entourageE _). HB.end. HB.structure Definition TAddAG := { A of TAddAG_Uniform A (* TODO: should be replaced by type alias TAddAG *) & TAddAG_wo_Uniform A }. (* TODO: should be omitted *) HB.factory Definition JoinTAddAG T & AddAG_of_TYPE T & Topological T := (JoinTAddAG_wo_Uniform T). HB.builders Context T (a : JoinTAddAG T). HB.instance Definition to_JoinTAddAG_wo_Uniform : JoinTAddAG_wo_Uniform T := a. (* TODO: Nice error message when factory builders do not depend on the source factory 'a'*) HB.instance Definition to_Uniform : TAddAG_Uniform T := let _ : JoinTAddAG T := a in TAddAG_Uniform.Build T. HB.end. (* Instance *) HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Example test1 (m n : Z) : (m + n) - n + 0 = m. Proof. by rewrite addrK addr0. Qed. Import Qcanon. Lemma Qcplus_opp_l q : - q + q = 0. Proof. by rewrite Qcplus_comm Qcplus_opp_r. Qed. HB.instance Definition Qc_ring_axioms := Ring_of_TYPE.Build Qc 0%Qc 1%Qc Qcplus Qcopp Qcmult Qcplus_assoc Qcplus_comm Qcplus_0_l Qcplus_opp_l Qcmult_assoc Qcmult_1_l Qcmult_1_r Qcmult_plus_distr_l Qcmult_plus_distr_r. Obligation Tactic := idtac. Definition Qcopen_base : set (set Qc) := [set A | exists a b : Qc, forall z, A z <-> a < z /\ z < b]. Program Definition QcTopological := TopologicalBase.Build Qc Qcopen_base _ _. Next Obligation. move=> x _; exists [set y | x - 1 < y < x + 1]. by exists (x - 1), (x + 1). split; rewrite Qclt_minus_iff. by rewrite -[_ + _]/(x - (x - 1))%G opprB addrCA subrr. by rewrite -[_ + _]/(x + 1 - x)%G addrAC subrr. Qed. Next Obligation. move=> X Y [aX [bX Xeq]] [aY [bY Yeq]] z [/Xeq [aXz zbX] /Yeq [aYz zbY]]. Admitted. HB.instance Definition _ : TopologicalBase Qc := QcTopological. Program Definition QcJoinTAddAG := JoinTAddAG.Build Qc _ _. Next Obligation. Admitted. Next Obligation. Admitted. #[verbose] HB.instance Definition _ : JoinTAddAG Qc := QcJoinTAddAG. Check (entourage : set (set (Qc * Qc))). (* TODO fix spill-factory-param-factories *) End Stage11. math-comp-hierarchy-builder-4d8a939/rocq-hierarchy-builder.opam000066400000000000000000000024001521677141400245740ustar00rootroot00000000000000opam-version: "2.0" name: "coq-hierarchy-builder" version: "dev" maintainer: "Enrico Tassi " authors: [ "Cyril Cohen" "Kazuhiko Sakaguchi" "Enrico Tassi" ] license: "MIT" homepage: "https://github.com/math-comp/hierarchy-builder" bug-reports: "https://github.com/math-comp/hierarchy-builder/issues" dev-repo: "git+https://github.com/math-comp/hierarchy-builder" build: [ [ make "build"] [ make "test-suite" ] {with-test & rocq-core:installed} ] install: [ make "install" ] depends: [ "rocq-core" {(>= "9.0" & < "9.3~") | = "dev"} & "rocq-elpi" {>= "3" | = "dev"} ] conflicts: [ "coq-hierarchy-builder" {< "1.9~"} "coq-hierarchy-builder-shim" ] depexts: [ [ "wdiff" ] {os-family = "debian" & with-test} ] synopsis: "High level commands to declare and evolve a hierarchy based on packed classes" description: """ Hierarchy Builder is a high level language to build hierarchies of algebraic structures and make these hierarchies evolve without breaking user code. The key concepts are the ones of factory, builder and abbreviation that let the hierarchy developer describe an actual interface for their library. Behind that interface the developer can provide appropriate code to ensure retro compatibility. """ tags: [ "logpath:HB" ] math-comp-hierarchy-builder-4d8a939/shim/000077500000000000000000000000001521677141400203165ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/shim/Makefile000066400000000000000000000003051521677141400217540ustar00rootroot00000000000000COQMAKEFILE?=$(COQBIN)coq_makefile build: $(COQMAKEFILE) -f _CoqProject -o Makefile.coq $(MAKE) -f Makefile.coq install: $(MAKE) -f Makefile.coq install clean: $(MAKE) -f Makefile.coq clean math-comp-hierarchy-builder-4d8a939/shim/_CoqProject000066400000000000000000000000251521677141400224460ustar00rootroot00000000000000-R . HB structures.vmath-comp-hierarchy-builder-4d8a939/shim/structures.v000066400000000000000000000007041521677141400227310ustar00rootroot00000000000000From Coq Require Import String ssreflect ssrfun. Export String.StringSyntax. Variant error_msg := NoMsg | IsNotCanonicallyA (x : Type). Definition unify T1 T2 (t1 : T1) (t2 : T2) (s : error_msg) := phantom T1 t1 -> phantom T2 t2. Definition id_phant {T} {t : T} (x : phantom T t) := x. Definition nomsg : error_msg := NoMsg. Definition is_not_canonically_a x := IsNotCanonicallyA x. Definition new {T} (x : T) := x. Definition eta {T} (x : T) := x. math-comp-hierarchy-builder-4d8a939/tests/000077500000000000000000000000001521677141400205205ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/about.v.out000066400000000000000000000130161521677141400226300ustar00rootroot00000000000000Toplevel input, character 0: > From Coq Require Import ZArith ssrfun ssreflect. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: "From Coq" has been replaced by "From Stdlib". [deprecated-from-Coq,deprecated-since-9.0,deprecated,default] HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.18000066400000000000000000000124251521677141400230620ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.19000066400000000000000000000124251521677141400230630ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/about.v.out.20000066400000000000000000000124251521677141400230530ustar00rootroot00000000000000HB: AddMonoid_of_TYPE is a factory (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE operations and axioms are: - zero - add - addrA - add0r - addr0 HB: AddMonoid_of_TYPE requires the following mixins: HB: AddMonoid_of_TYPE provides the following mixins: - AddMonoid_of_TYPE HB: AddMonoid_of_TYPE.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddMonoid_of_TYPE.Build requires its subject to be already equipped with: HB: AddMonoid_of_TYPE.Build provides the following mixins: - AddMonoid_of_TYPE HB: arguments: AddMonoid_of_TYPE.Build S zero add addrA add0r addr0 - S : Type - zero : AddMonoid.sort S - add : S -> S -> S - addrA : associative add - add0r : left_id 0%G add - addr0 : right_id 0%G add HB: AddAG.type is a structure (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.type characterizing operations and axioms are: - addNr - opp HB: AddAG is a factory for the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid (* new, not from inheritance *) HB: AddAG inherits from: - AddMonoid - AddComoid HB: AddAG is inherited by: - Ring HB: AddMonoid.type is a structure (from "./examples/demo1/hierarchy_5.v", line 17) HB: AddMonoid.type characterizing operations and axioms are: - addr0 - add0r - addrA - add - zero HB: AddMonoid is a factory for the following mixins: - AddMonoid_of_TYPE (* new, not from inheritance *) HB: AddMonoid inherits from: HB: AddMonoid is inherited by: - AddComoid - AddAG - BiNearRing - SemiRing - Ring HB: Ring_of_AddAG is a factory (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG operations and axioms are: - one - mul - mulrA - mulr1 - mul1r - mulrDl - mulrDr HB: Ring_of_AddAG requires the following mixins: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG provides the following mixins: - BiNearRing_of_AddMonoid Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: Ring_of_AddAG.Build is a factory constructor (from "./examples/demo1/hierarchy_5.v", line 108) HB: Ring_of_AddAG.Build requires its subject to be already equipped with: - AddMonoid_of_TYPE - AddComoid_of_AddMonoid - AddAG_of_AddComoid HB: Ring_of_AddAG.Build provides the following mixins: - BiNearRing_of_AddMonoid HB: arguments: Ring_of_AddAG.Build A [one] [mul] mulrA mulr1 mul1r mulrDl mulrDr - A : Type - one : A - mul : A -> A -> A - mulrA : associative mul - mulr1 : left_id one mul - mul1r : right_id one mul - mulrDl : left_distributive mul add - mulrDr : right_distributive mul add Doc: Builds a Ring from an Abelian Group: the absorbing properties mul0r and mul0r are derived from addrC and the other ring axioms, following a proof of Hankel (Gerhard Betsch. On the beginnings and development of near-ring theory. In Near-rings and near-fields. Proceedings of the conference held in Fredericton, New Brunswick, July 18-24, 1993, pages 1–11. Mathematics and its Applications, 336. Kluwer Academic Publishers Group, Dordrecht, 1995). HB: add is an operation of structure AddMonoid (from "./examples/demo1/hierarchy_5.v", line 17) HB: add comes from mixin AddMonoid_of_TYPE (from "./examples/demo1/hierarchy_5.v", line 10) HB: AddAG.sort is a canonical projection (from "./examples/demo1/hierarchy_5.v", line 73) HB: AddAG.sort has the following canonical values: - Ring.sort (from "./examples/demo1/hierarchy_5.v", line 196) - Z HB: AddAG.sort is a coercion from AddAG to Sortclass (from "./examples/demo1/hierarchy_5.v", line 73) HB: Z is canonically equipped with structures: - AddMonoid AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) HB: hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) HB: hierarchy_5_Ring__to__hierarchy_5_SemiRing is a coercion from Ring to SemiRing (from "./examples/demo1/hierarchy_5.v", line 196) Toplevel input, character 15: > HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: HB: unable to locate Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid HB: synthesized in file File "(stdin)", line 5, column 0, character 127: Interactive Module hierarchy_5 started Interactive Module AddComoid started HB: Z is canonically equipped with structures: - AddMonoid demo1.hierarchy_5.AddComoid AddAG (from "(stdin)", line 5) - BiNearRing SemiRing Ring (from "(stdin)", line 10) math-comp-hierarchy-builder-4d8a939/tests/bug_435.v000066400000000000000000000015161521677141400220620ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M T := { m : bool }. HB.structure Definition S := {T of M T}. HB.mixin Record A1 X T := { a1 : bool }. HB.structure Definition B1 X := {T of A1 X T}. HB.instance Definition _ (X : Type) := A1.Build X unit true. HB.mixin Record A2 (X : Type) T := { a2 : bool }. HB.structure Definition B2 (X : Type) := {T of A2 X T}. (* This should work but fails. *) Module should_work_but_fails. HB.structure Definition B (X : S.type) := {T of A1 X T & A2 X T}. #[verbose] HB.instance Definition _ (X : Type) := A2.Build X unit true. HB.saturate unit. Check unit : B.type _. End should_work_but_fails. Module workaround. HB.instance Definition _ (X : Type) := A2.Build X unit true. HB.structure Definition B (X : S.type) := {T of A1 X T & A2 X T}. HB.saturate unit. Check unit : B.type _. End workaround.math-comp-hierarchy-builder-4d8a939/tests/bug_447.v000066400000000000000000000016061521677141400220650ustar00rootroot00000000000000From HB Require Import structures. Variant testTy := A | B. HB.mixin Record Stack1 T := { prop1 : unit }. HB.structure Definition JustStack1 := { T of Stack1 T }. HB.mixin Record Stack1Param R T := { prop2 : unit }. HB.structure Definition JustStack1Param R := { T of Stack1Param R T }. HB.mixin Record Stack2 T := { prop3 : unit }. HB.structure Definition JustStack2 := { T of Stack2 T }. HB.mixin Record Mixed T & Stack1 T & Stack2 T := { prop4 : unit }. HB.structure Definition JustMixed := { T of Mixed T & Stack1 T & Stack2 T}. HB.structure Definition JustMixedParam R := { T of Mixed T & Stack1 T & Stack1Param R T & Stack2 T}. HB.instance Definition _ := @Stack1.Build testTy tt. HB.instance Definition _ := @Stack2.Build testTy tt. HB.instance Definition _ {R} := @Stack1Param.Build R testTy tt. HB.instance Definition _ := @Mixed.Build testTy tt. Check testTy : JustMixedParam.type _. math-comp-hierarchy-builder-4d8a939/tests/class_for.v000066400000000000000000000015371521677141400226700ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. (* without params *) HB.mixin Record isInhab T := { x : T }. HB.structure Definition Inhab := { T of isInhab T }. Definition unit' := unit. HB.instance Definition _ := isInhab.Build unit' tt. Check Inhab.of unit'. Fail Check Inhab.of unit. HB.instance Definition _ := Inhab.copy unit unit'. Check Inhab.of unit. (* with params *) HB.mixin Record isInhabIf (b : bool) (T : Type) := { y : forall ph : phant T, (match b with true => T | false => unit end) }. HB.structure Definition InhabIf b := { T of isInhabIf b T }. Definition bool' := bool. HB.instance Definition _ := isInhabIf.Build true bool' (fun=> false). Check InhabIf.of bool'. Fail Check InhabIf.of bool. HB.instance Definition _ := InhabIf.copy bool bool'. Check InhabIf.of bool. Check (y (Phant bool) : bool). math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v000066400000000000000000000017651521677141400234010ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB (p : unit) T & A T := { b : T }. HB.structure Definition B p := {T of A T & hasB p T}. HB.mixin Record hasC (p q : unit) T & B p T := { c : T }. HB.structure Definition C p q := {T of B p T & hasC p q T}. HB.mixin Record hasD T & C tt tt T := { d : T }. HB.structure Definition D := {T of C tt tt T & hasD T}. #[compress_coercions] HB.instance Definition prodA (A A' : A.type) := hasA.Build (A * A')%type (a, a). #[compress_coercions] HB.instance Definition prodB p (B B' : B.type p) := hasB.Build p (B * B')%type (b, b). #[compress_coercions] HB.instance Definition prodC p q (C C' : C.type p q) := hasC.Build p q (C * C')%type (c, c). #[compress_coercions] HB.instance Definition prodD (D D' : D.type) := hasD.Build (D * D')%type (d, d). Set Printing Coercions. Print Datatypes_prod__canonical__compress_coe_D. math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out000066400000000000000000000012671521677141400242040ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.18000066400000000000000000000012671521677141400244330ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.19000066400000000000000000000012671521677141400244340ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/compress_coe.v.out.20000066400000000000000000000012671521677141400244240ustar00rootroot00000000000000Datatypes_prod__canonical__compress_coe_D = fun D D' : D.type => {| D.sort := D.sort D * D.sort D'; D.class := {| D.compress_coe_hasA_mixin := prodA (compress_coe_D__to__compress_coe_A D) (compress_coe_D__to__compress_coe_A D'); D.compress_coe_hasB_mixin := prodB tt (compress_coe_D__to__compress_coe_B D) (compress_coe_D__to__compress_coe_B D'); D.compress_coe_hasC_mixin := prodC tt tt (compress_coe_D__to__compress_coe_C D) (compress_coe_D__to__compress_coe_C D'); D.compress_coe_hasD_mixin := prodD D D' |} |} : D.type -> D.type -> D.type Arguments Datatypes_prod__canonical__compress_coe_D D D' math-comp-hierarchy-builder-4d8a939/tests/declare.v000066400000000000000000000020501521677141400223030ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB (p : unit) T & A T := { b : T }. HB.structure Definition B p := {T of A T & hasB p T}. HB.mixin Record hasC (p q : unit) T & B p T := { c : T }. HB.structure Definition C p q := {T of B p T & hasC p q T}. Section test. HB.declare Context p q T & hasA T & hasB p T & hasC p q T. Definition test := [the C.type _ _ of T]. End test. HB.factory Record hasABC (p q : unit) T := { a : T; b : T; c : T}. HB.builders Context p q T & hasABC p q T. HB.instance Definition _ := hasA.Build T a. HB.instance Definition _ := hasB.Build p T b. HB.instance Definition _ := hasC.Build p q T c. HB.end. Section test2. HB.declare Context p q T & hasABC p q T. Definition test2 := [the C.type _ _ of T]. End test2. (* broken *) (* Section test3. Definition copy : Type -> Type := id. HB.declare Context p T of hasABC p tt (copy T). Definition test3 := [the C.type _ _ of copy T]. End test3. *) math-comp-hierarchy-builder-4d8a939/tests/display.v000066400000000000000000000001641521677141400223550ustar00rootroot00000000000000From HB Require Import structures. #[key="T"] HB.mixin Record m (d : unit) (T : Type) := { op : T -> T -> T; }. math-comp-hierarchy-builder-4d8a939/tests/duplicate_structure.v000066400000000000000000000003721521677141400250030ustar00rootroot00000000000000From HB Require Import structures. Definition comb A op := forall x : A, op (op x) = x. HB.mixin Record Foo A := { op : A -> A; ax : comb A op }. HB.structure Definition S1 := { A of Foo A }. Fail HB.structure Definition S2 := { A of Foo A }. math-comp-hierarchy-builder-4d8a939/tests/err_bad_mix.v000066400000000000000000000007021521677141400231610ustar00rootroot00000000000000From HB Require Import structures. Module Test. HB.mixin Record Mixin T := { zero: T; }. HB.structure Definition Struct := { T of Mixin T }. HB.instance Definition struct_bool := Mixin.Build bool true. Module Exports. HB.reexport. End Exports. End Test. (** Uncommenting any of these two prevents the issue *) (* Export Test.Exports. *) (* HB.export Test. *) Fail HB.instance Definition struct_nat := Test.Mixin.Build nat 0. math-comp-hierarchy-builder-4d8a939/tests/err_bad_mix.v.out000066400000000000000000000003351521677141400237710ustar00rootroot00000000000000Interactive Module Test started Interactive Module Exports started The command has indeed failed with message: HB: Test.Mixin.axioms_ is not a factory or its library (HB.tests.err_bad_mix.Test) was not correctly imported math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v000066400000000000000000000003131521677141400242340ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M T := {}. HB.structure Definition S := { x of M x }. HB.instance Definition _ : M nat := M.Build nat. HB.instance Definition _ : M nat := M.Build nat.math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out000066400000000000000000000003221521677141400250420ustar00rootroot00000000000000Toplevel input, character 0: > HB.instance Definition _ : M nat := M.Build nat. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.18000066400000000000000000000001561521677141400252760ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.19000066400000000000000000000001561521677141400252770ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_instance_nop.v.out.20000066400000000000000000000001561521677141400252670ustar00rootroot00000000000000Toplevel input, character 155: Warning: HB: no new instance is generated [HB.no-new-instance,HB,elpi,default] math-comp-hierarchy-builder-4d8a939/tests/err_miss_dep.v000066400000000000000000000005041521677141400233610ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record IsAddComoid A := {}. HB.structure Definition AddComoid := { A of IsAddComoid A }. HB.mixin Record IsAbelianGrp A & IsAddComoid A := {}. HB.structure Definition AbelianGrp := { A of IsAbelianGrp A }. Fail HB.mixin Record IsRing K & IsAbelianGrp K (*& IsAddComoid K*) := {}. math-comp-hierarchy-builder-4d8a939/tests/err_miss_dep.v.out000066400000000000000000000006541521677141400241750ustar00rootroot00000000000000Toplevel input, character 0: > HB.structure Definition AbelianGrp := { A of IsAbelianGrp A }. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: pulling in dependencies: [err_miss_dep_IsAddComoid] Please list them or end the declaration with '&' [HB.implicit-structure-dependency,HB,elpi,default] The command has indeed failed with message: HB: Unable to find mixin err_miss_dep_IsAddComoid on subject K math-comp-hierarchy-builder-4d8a939/tests/err_miss_key.v000066400000000000000000000001241521677141400233770ustar00rootroot00000000000000From HB Require Import structures. Fail #[key="Tmiss"] HB.mixin Record Foo T := {}.math-comp-hierarchy-builder-4d8a939/tests/err_miss_key.v.out000066400000000000000000000001631521677141400242100ustar00rootroot00000000000000The command has indeed failed with message: HB: The #[key="Tmiss"] attribute does not match the selected subject T math-comp-hierarchy-builder-4d8a939/tests/err_missin_subject.v000066400000000000000000000003701521677141400246000ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M X := {}. HB.structure Definition S := { X of M X}. HB.instance Definition _ : M nat := M.Build _. HB.instance Definition _ : M _ := M.Build bool. Fail HB.instance Definition _ : M _ := M.Build _.math-comp-hierarchy-builder-4d8a939/tests/err_missin_subject.v.out000066400000000000000000000003101521677141400254000ustar00rootroot00000000000000The command has indeed failed with message: HB: The instance subject must be explicitly given. Use: HB.instance Definition _ : M := ... HB.instance Definition _ := M.Build ... math-comp-hierarchy-builder-4d8a939/tests/factory_sort.v000066400000000000000000000016071521677141400234310ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. #[verbose] HB.mixin Record hasA T := { a : T }. About hasA.type. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB T := { b : T }. About hasB.type. HB.structure Definition B := {T of hasB T}. HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T }. HB.builders Context T & hasAB T. HB.instance Definition _ := AB.copy T (AB.pack T (hasB.Build (hasA.Build T a) b)). HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose Tab := hasB.Build Ta b. exact: P (AB.pack T Tab). Qed. Goal forall T (a b : T), G. Proof. move=> T a b. exact: P [the AB.type of hasAB.Build T a b : Type]. Qed. End test. math-comp-hierarchy-builder-4d8a939/tests/factory_when_notation.v000066400000000000000000000003321521677141400253100ustar00rootroot00000000000000From HB Require Import structures. Notation x := (fun x : nat => true). HB.mixin Record m T := {x : T}. HB.factory Record f T := { x : T }. HB.builders Context T & f T. HB.instance Definition _ := m.Build T x. HB.end. math-comp-hierarchy-builder-4d8a939/tests/fix_loop.v000066400000000000000000000001621521677141400225250ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M A := { x: nat }. HB.structure Definition S := { A of M A }. math-comp-hierarchy-builder-4d8a939/tests/fun_instance.v000066400000000000000000000005411521677141400233630ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. HB.mixin Record HasA T := { a : T }. HB.structure Definition A := { T of HasA T }. HB.instance Definition _ T (T' : A.type) := HasA.Build (T -> T') (fun=> a). HB.instance Definition _ := HasA.Build Prop True. HB.instance Definition _ := HasA.Build Type nat. math-comp-hierarchy-builder-4d8a939/tests/grefclass.v000066400000000000000000000003751521677141400226650ustar00rootroot00000000000000From HB Require Import structures. Definition pred T := T -> bool. HB.mixin Record isPredNat (f : pred nat) := {}. HB.structure Definition PredNat := {f of isPredNat f}. Section TestSort. Variable p : PredNat.type. Check p : pred nat. End TestSort. math-comp-hierarchy-builder-4d8a939/tests/hb_pack.v000066400000000000000000000053631521677141400223050ustar00rootroot00000000000000Require Import ssreflect ssrfun ssrbool. From elpi Require Import elpi. From HB Require Import structures. #[verbose] HB.mixin Record hasA T := { a : T }. About hasA.type. HB.structure Definition A := {T of hasA T}. HB.mixin Record hasB T := { b : T * T }. About hasB.type. HB.structure Definition B := {T of hasB T}. #[short(pack="AB.pack")] HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T * T }. HB.builders Context T & hasAB T. Definition xxx := HB.pack_for AB.type T (hasB.Build T b) (hasA.Build T a). HB.instance Definition _ := AB.copy T xxx. HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). (* problem with planB Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A := ltac:(elpi HB.pack_for (A.type) (T) (Ta)). pose Tab := hasB.Build A (b,b). pose AB : AB.type := ltac:(elpi HB.pack (A) (Tab)). exact: P AB. Qed. *) Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A := HB.pack_for A.type T Ta. pose Tab := hasB.Build A (b,b). pose AB := HB.pack_for AB.type A Tab. exact: P AB. Qed. Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build _ a. pose A : A.type := HB.pack T Ta. pose Tab := hasB.Build A (b,b). pose AB : AB.type := HB.pack A Tab. exact: P AB. Qed. Check forall T : AB.type, let x := AB.pack T in x. Goal forall T (a b : T), G. Proof. move=> T a b. unshelve epose (A := HB.pack_for A.type T (_ : hasA T)). by exact: (hasA.Build _ a). Check A : A.type. unshelve epose (A1 := HB.pack_for A.type T (hasA.Build T _)). by exact: a. Check A : A.type. pose AB1 := AB.pack A (_ : hasB _). Check AB1 : hasB A -> AB.type. have [:Bm] @AB2 := AB.pack A (Bm : hasB A). by exact: (hasB.Build _ (b,b)). Check Bm : hasB A. Check AB2 : AB.type. have [:pB] @AB3 := AB.pack A (hasB.Build A pB). by exact: (b,b). Check pB : T * T. Check AB3 : AB.type. have [:pA pB'] @AB4 := AB.pack T (hasAB.Build A pA pB'). by exact: a. by exact: (b,b). exact: P AB4. Qed. End test. HB.mixin Record HasFoo (A : Type) (P : A -> Prop) T := { foo : forall x, P x -> T; }. #[short(pack="Foo.pack")] HB.structure Definition Foo A P := { T of HasFoo A P T }. Section test2. Variable A : Type. Variable P : A -> Prop. Goal forall T, (forall x, P x -> T) -> True. intros T H. pose X := Foo.pack T (HasFoo.Build A P T H). Check X : Foo.type A P. Abort. End test2. HB.mixin Record isID T (F : T -> T) := { p : forall x : T, F x = x }. HB.structure Definition Fun T := { F of isID T F }. Goal forall f : nat -> nat, forall p : (forall x, f x = x ), True. intros f p. pose F := isID.Build nat f p. pose T : Fun.type nat := HB.pack f F. Check T : Fun.type nat. Abort. math-comp-hierarchy-builder-4d8a939/tests/hnf.v000066400000000000000000000007351521677141400214670ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record M A := { x: nat }. HB.structure Definition S := { X of M X}. HB.factory Record f A := { y : nat }. HB.builders Context T & f T. HB.instance Definition _ := M.Build T (y + 1). HB.end. #[hnf] HB.instance Definition _ := f.Build nat (3 + 2). Print Datatypes_nat__canonical__hnf_S. Print HB_unnamed_mixin_8. HB.instance Definition _ := f.Build bool (3 + 2). Print Datatypes_bool__canonical__hnf_S. Print HB_unnamed_mixin_12. math-comp-hierarchy-builder-4d8a939/tests/hnf.v.out000066400000000000000000000006651521677141400222770ustar00rootroot00000000000000Datatypes_nat__canonical__hnf_S = {| S.sort := nat; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_8 |} |} : S.type HB_unnamed_mixin_8 = {| M.x := f.y nat HB_unnamed_factory_6 + 1 |} : M.axioms_ nat Datatypes_bool__canonical__hnf_S = {| S.sort := bool; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_12 |} |} : S.type HB_unnamed_mixin_12 = Builders_1.HB_unnamed_factory_3 bool HB_unnamed_factory_9 : M.axioms_ bool math-comp-hierarchy-builder-4d8a939/tests/hnf.v.out.16000066400000000000000000000006711521677141400225210ustar00rootroot00000000000000Datatypes_nat__canonical__hnf_S = {| S.sort := nat; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_8 |} |} : S.type HB_unnamed_mixin_8 = {| M.x := f.y nat HB_unnamed_factory_6 + 1 |} : M.axioms_ nat Datatypes_bool__canonical__hnf_S = {| S.sort := bool; S.class := {| S.hnf_M_mixin := HB_unnamed_mixin_12 |} |} : S.type HB_unnamed_mixin_12 = Builders_2.HB_unnamed_factory_4 bool HB_unnamed_factory_9 : M.axioms_ bool math-comp-hierarchy-builder-4d8a939/tests/howto.v.out000066400000000000000000000070261521677141400226620ustar00rootroot00000000000000Toplevel input, character 0: > From Coq Require Import ZArith ssrfun ssreflect. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: "From Coq" has been replaced by "From Stdlib". [deprecated-from-Coq,deprecated-since-9.0,deprecated,default] HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.18000066400000000000000000000064351521677141400231140ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.19000066400000000000000000000064351521677141400231150ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/howto.v.out.20000066400000000000000000000064351521677141400231050ustar00rootroot00000000000000HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid - AddComoid_of_TYPE; AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddComoid_of_TYPE; AddAG_of_AddComoid; Ring_of_AddAG - AddComoid_of_TYPE; AddAG_of_AddComoid; SemiRing_of_AddComoid - AddMonoid_of_TYPE; AddComoid_of_AddMonoid; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_TYPE - AddAG_of_TYPE; BiNearRing_of_AddMonoid - AddAG_of_TYPE; Ring_of_AddAG - AddAG_of_TYPE; SemiRing_of_AddComoid - AddComoid_of_TYPE; Ring_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances The command has indeed failed with message: HB: no solution found, try to increase search depth. HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - Ring_of_AddComoid - AddAG_of_AddComoid; BiNearRing_of_AddMonoid - AddAG_of_AddComoid; Ring_of_AddAG - AddAG_of_AddComoid; SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: solutions (use 'HB.about F.Build' to see the arguments of each factory F): - BiNearRing_of_AddMonoid - Ring_of_AddAG - SemiRing_of_AddComoid For a guide on declaring MathComp instances please refer to the following link: https://github.com/math-comp/math-comp/wiki/How-to-declare-MathComp-instances HB: nothing to do. math-comp-hierarchy-builder-4d8a939/tests/instance_before_structure.v000066400000000000000000000013761521677141400261640ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.mixin Record m3 T := { default3 : T }. HB.structure Definition s1 := { T of m1 T }. HB.instance Definition _ : m1 nat := m1.Build nat 1. HB.about nat. (* too early *) HB.instance Definition _ : m2 nat := m2.Build nat 2. HB.about nat. (* only s1 on nat *) HB.instance Definition _ : m3 nat := m3.Build nat 3. HB.structure Definition s2 := { T of m1 T & m2 T }. HB.about nat. (* s2 is not there yet *) HB.structure Definition s3 := { T of m3 T }. HB.about nat. (* s2 has been instanciated but not s3 *) (* here it works *) HB.saturate. HB.about nat. (* all there *) Check @default1 nat. Check @default2 nat. Check @default3 nat. math-comp-hierarchy-builder-4d8a939/tests/instance_merge.v000066400000000000000000000000001521677141400236600ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/instance_merge_with_distinct_param.v000066400000000000000000000031151521677141400300060ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition nat_m1 := m1.Build nat 0. HB.instance Definition nat_m2 := m2.Build nat 1. (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2 (X : s2.type) : m2 (list X) := m2.Build (list X) (cons default2 nil). HB.structure Definition s3 := { T of m1 T & m2 T }. (* since we can preserve m1 and m2 with list, we can preserve s3 as well ! *) (* if we have a file A with definitions of S1 and S2, file B importing Awith definitions of instance nat_m1 and nat_m2 file C importing A with the definition of s3 in a file D that imports B and C if we call saturate_instance, we create the instance for s3. this example shows the need for a separate command *) Fail Check nat : s3.type. HB.saturate. Check nat : s3.type. (* since nat satisfies s3.type, so does list nat *) Check list nat : s3.type. Check list (list nat) : s3.type. Fail Check fun t : s1.type => (list t : s3.type). Fail Check fun t : s2.type => (list t : s3.type). Check fun t : s3.type => (list t : s3.type). math-comp-hierarchy-builder-4d8a939/tests/instance_merge_with_param.v000066400000000000000000000014451521677141400261110ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition _ (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). HB.instance Definition list_m2 (X : s1.type) : m2 (list X) := m2.Build (list X) nil. HB.structure Definition s3 := { T of m1 T & m2 T }. HB.about list. (* should have s3 *) (* The s3 instance on list should be synthetized automatically, *) (* But since it's defined afterwards, it's not taken into account. *) (* The subtelty now is that there is a parameter, but it's always the same *) (* A simple recall suffices: *) HB.instance Definition _ (X : s1.type) := list_m2 X. HB.about list. math-comp-hierarchy-builder-4d8a939/tests/instance_params_no_type.v000066400000000000000000000020511521677141400256110ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.instance Definition nat_foo P := is_foo.Build P nat (fun _ x => x). HB.instance Definition list_foo P := is_foo.Build P (list P) (fun _ x => x). HB.instance Definition list_foo' P A:= is_foo.Build P (list A) (fun _ x => x). About list_foo'. HB.structure Definition foo P := { A of is_foo P A }. (* .... list A .... (fun A => {| foo.sort := list..; foo.class := {| foo.instance_params_no_type_is_foo_mixin := list_foo A |} |} ). HB.about foo. *) (* Elpi Trace Browser. *) Check nat_foo. Check list_foo. HB.mixin Record is_b A:= { default : A }. Check foo.type. Print foo.type. Print Module foo. Print foo.axioms_. (*Elpi Trace Browser. *) HB.structure Definition b := { A of is_b A}. HB.instance Definition nat_b := is_b.Build nat 0. HB.mixin Record is_bar (P : b.type) A := { test : P -> A -> A }. HB.structure Definition bar P := { A of is_bar P A}. HB.instance Definition list_bar P := is_bar.Build P (list P) (fun _ x => x). Check list_bar. math-comp-hierarchy-builder-4d8a939/tests/interleave_context.v000066400000000000000000000016541521677141400246170ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun ssrbool. From HB Require Import structures. HB.mixin Record HasA (n : nat) T := { a : T }. HB.structure Definition A n := { T of HasA n T }. HB.mixin Record HasB (X : A.type 0) (T : Type) := { b : X -> T }. HB.structure Definition B (X : A.type 0) := { T of HasB X T }. (* Since `B` expects an argument of type `A.type 0` (and not just just the naked type `T`) we pass `A.clone 0 T _` (of type `A.type 0`) and inference uses the first parameter `A` to elaborate it. *) HB.mixin Record IsSelfA T & A 0 T & B (A.clone 0 T _) T := {}. HB.structure Definition SelfA := { T of IsSelfA T }. HB.factory Record IsSelfA' T := { a : T ; b : T -> T}. HB.builders Context T & IsSelfA' T. HB.instance Definition _ := HasA.Build 0 T a. HB.instance Definition _ := HasB.Build _ T b. HB.instance Definition _ := IsSelfA.Build T. HB.end. HB.instance Definition _ := IsSelfA'.Build nat 0 id. math-comp-hierarchy-builder-4d8a939/tests/issue284.v000066400000000000000000000010071521677141400222730ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record X_of_Type Ω := {}. HB.structure Definition X := {Ω of X_of_Type Ω}. HB.instance Definition XProp := X_of_Type.Build Prop. Definition prop := Prop. HB.instance Definition Xprop := X_of_Type.Build prop. HB.instance Definition XSet := X_of_Type.Build Set. Definition set := Set. HB.instance Definition Xset := X_of_Type.Build set. HB.instance Definition XType := X_of_Type.Build Type. Definition type := Type. HB.instance Definition Xtype := X_of_Type.Build type. math-comp-hierarchy-builder-4d8a939/tests/issue287.v000066400000000000000000000007611521677141400223040ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record InhMixin T := { point : T; }. HB.structure Definition Inh := { T of InhMixin T }. HB.instance Definition nat_inh := InhMixin.Build nat 0. Section ProdInh. Variables (T S : Inh.type). (* This works fine *) HB.instance Definition prod_inh := InhMixin.Build (T * S)%type (point, point). End ProdInh. Section FunInh. Variables (T S : Inh.type). HB.instance Definition fun_inh := InhMixin.Build (T -> S) (fun _ => point). End FunInh. math-comp-hierarchy-builder-4d8a939/tests/local_instance.v000066400000000000000000000004361521677141400236700ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record def A := { default : A }. HB.structure Definition nonempty := { T of def T }. Section Box. #[local] HB.instance Definition def_nat := def.Build nat 1. Check default : nat. End Box. #[fail, skip="8.11"] HB.check (default : nat). math-comp-hierarchy-builder-4d8a939/tests/lock.v000066400000000000000000000005421521677141400216400ustar00rootroot00000000000000From HB Require Import structures. HB.lock Definition foo := 3. Definition nat1 := nat. HB.lock Definition bar : nat1 := 3. HB.lock Definition baz n : nat := 3 + n. Module Import X. Axiom bigbody : Type -> Type -> Type. Axiom bigop : forall R I : Type, R -> list I -> (I -> bigbody R I) -> R. HB.lock Definition big := bigop. End X. About big. math-comp-hierarchy-builder-4d8a939/tests/log_impargs_record.v000066400000000000000000000003741521677141400245540ustar00rootroot00000000000000From HB Require Import structures. Set Implicit Arguments. #[log] HB.mixin Record A T := { a : T; f : T -> T; p : forall x : T, f x = x -> True; q : forall h : f a = a, p _ h = p _ h; }. HB.structure Definition S := { T of A T }. About A.p.math-comp-hierarchy-builder-4d8a939/tests/missing_join_error.v000066400000000000000000000011301521677141400246030ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record isTop M := { }. HB.structure Definition Top := {M of isTop M}. HB.mixin Record isA1 M & Top M := { }. HB.structure Definition A1 := {M of isA1 M & isTop M}. HB.mixin Record isA2 M & Top M := { }. HB.structure Definition A2 := {M of isA2 M & isTop M}. HB.mixin Record isB1 M & A1 M := { }. HB.structure Definition B1 := {M of isB1 M & }. HB.mixin Record isB2 M & A2 M := { }. HB.structure Definition B2 := {M of isB2 M & isA2 M }. HB.structure Definition B2A1 := {M of B2 M & A1 M }. Fail HB.structure Definition A2B1 := {M of A2 M & B1 M }. math-comp-hierarchy-builder-4d8a939/tests/missing_join_error.v.out000066400000000000000000000011601521677141400254140ustar00rootroot00000000000000Toplevel input, character 0: > HB.structure Definition B2 := {M of isB2 M & isA2 M }. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning: pulling in dependencies: [missing_join_error_isTop] Please list them or end the declaration with '&' [HB.implicit-structure-dependency,HB,elpi,default] The command has indeed failed with message: You must declare the hierarchy bottom-up or add a missing join. There are two ways out: - declare structure A2B1 before structure B2A1 if B2A1 inherits from it; - declare an additional structure that inherits from both A1 and A2 and from which A2B1 and/or B2A1 inherit. math-comp-hierarchy-builder-4d8a939/tests/non_forgetful_inheritance.v000066400000000000000000000044441521677141400261350ustar00rootroot00000000000000From HB Require Import structures. Require Import ssreflect ssrfun ssrbool. HB.mixin Record HasMul T := { mul : T -> T -> T; }. HB.structure Definition Mul := { T of HasMul T }. HB.mixin Record HasSq T := { sq : T -> T; }. HB.structure Definition Sq := { T of HasSq T }. (* We need a functorial construction (a container) which preserves both structures. The simplest one is the option type. *) Definition option_mul {T : Mul.type} (o1 o2 : option T) : option T := match o1, o2 with | Some n, Some m => Some (mul n m) | _, _ => None end. HB.instance Definition _ (T : Mul.type) := HasMul.Build (option T) option_mul. Definition option_square {T : Sq.type} (o : option T) : option T := match o with | Some n => Some (sq n) | None => None end. HB.instance Definition _ (T : Sq.type) := HasSq.Build (option T) option_square. (* Now we mix the two unrelated structures by building Sq out of Mul. *** This breaks Forgetful Inheritance *** https://math-comp.github.io/competing-inheritance-paths-in-dependent-type-theory/ hence, HB prevents us from using it without care. *) Set Warnings "+HB.non-forgetful-inheritance". Fail HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As advised by the error message, we contain the problem in a module *) Module MulSq. #[non_forgetful_inheritance] HB.instance Definition _ (T : Mul.type) := HasSq.Build T (fun x => mul x x). (* As we expect we can proved this (by reflexivity) *) Lemma sq_mul (V : Mul.type) (v : V) : sq v = mul v v. Proof. by reflexivity. Qed. Lemma problem (W : Mul.type) (w : option W) : sq w = mul w w. Proof. Fail reflexivity. (* What? It used to work! *) Fail rewrite sq_mul. (* Lemmas don't cross the container either! *) (* Let's investigate *) rewrite /mul/= /sq/=. (* As we expect, we are on the option type. In the LHS it is the Sq built using the NFI instance option_square w = option_mul w w *) rewrite /option_mul/=. rewrite /option_square/sq/=. congr (match w with Some n => _ | None => None end). (* The branches for Some differ, since w is a variable, they don't compare as equal (fun n : W => Some (mul n n)) = (fun n : W => match w with | Some m => Some (mul n m) | None => None end) *) Abort. End MulSq.math-comp-hierarchy-builder-4d8a939/tests/not_same_key.v000066400000000000000000000003011521677141400233560ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record A T := { a : T }. #[key="T"] HB.mixin Record B T1 (T : Type) := { b : T -> T1 }. Fail HB.structure Definition sAB T1 := {T of A T & B T T1}.math-comp-hierarchy-builder-4d8a939/tests/not_same_key.v.out000066400000000000000000000001221521677141400241650ustar00rootroot00000000000000The command has indeed failed with message: HB: all mixins must have the same key math-comp-hierarchy-builder-4d8a939/tests/packable.v000066400000000000000000000025421521677141400224540ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record AddComoid_of_TYPE A := { zero : A; add : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; }. HB.structure Definition AddComoid := { A of AddComoid_of_TYPE A }. HB.mixin Record Ring_of_AddComoid A & AddComoid A := { opp : A -> A; one : A; mul : A -> A -> A; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. HB.factory Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[verbose] HB.builders Context A (a : Ring_of_TYPE A). HB.instance Definition to_AddComoid_of_TYPE := AddComoid_of_TYPE.Build A zero add addrA addrC add0r. HB.instance Definition to_Ring_of_AddComoid := Ring_of_AddComoid.Build A _ _ _ addNr mulrA mul1r mulr1 mulrDl mulrDr. HB.end. (* End change *) HB.structure Definition Ring := { A of Ring_of_TYPE A }. math-comp-hierarchy-builder-4d8a939/tests/primitive_records.v000066400000000000000000000020121521677141400244330ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From elpi Require Import elpi. From HB Require Import structures. Elpi Command HB.test. #[primitive] HB.mixin Record hasA T := { a : T }. Elpi Query lp:{{ coq.locate "hasA.axioms_" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. #[primitive] HB.structure Definition A := {T of hasA T}. Elpi Query lp:{{ coq.locate "A.axioms_" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. Elpi Query lp:{{ coq.locate "A.type" (indt Ind), std.assert! (coq.env.record? Ind tt) "not primitive" }}. (* Issue #248 *) #[primitive] HB.mixin Record HasMul T := { mul : T -> T -> T; mulC: forall x y : T, mul x y = mul y x; mulA: associative mul; }. #[primitive] HB.structure Definition Mul := { T of HasMul T }. #[primitive] HB.mixin Record HasSq T & Mul T := { sq : T -> T; pmul : forall x y, sq (mul x y) = mul (sq x) (sq y); }. #[primitive] HB.structure Definition Sq := { T of HasSq T & Mul T }. Check erefl : Sq.sort _ = Mul.sort _. math-comp-hierarchy-builder-4d8a939/tests/saturate_export.v000066400000000000000000000013351521677141400241420ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record HasPoint T := { default : T }. HB.instance Definition _ : HasPoint nat := HasPoint.Build nat 0. HB.instance Definition _ : HasPoint bool := HasPoint.Build bool false. HB.instance Definition _ A : HasPoint (list A) := HasPoint.Build (list A) nil. HB.instance Definition _ A : HasPoint Type := HasPoint.Build Type nat. HB.structure Definition Pointed := { T of HasPoint T }. Fail Check (list unit : Pointed.type). Module Foo. HB.saturate (list _). Module E. HB.reexport. End E. End Foo. Import Foo.E. Fail Check (list unit : Pointed.type). Module Bar. #[export] HB.saturate (list _). Module E. HB.reexport. End E. End Bar. Import Bar.E. Check (list unit : Pointed.type). math-comp-hierarchy-builder-4d8a939/tests/saturate_on.v000066400000000000000000000011071521677141400232320ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record HasPoint T := { default : T }. HB.instance Definition _ : HasPoint nat := HasPoint.Build nat 0. HB.instance Definition _ : HasPoint bool := HasPoint.Build bool false. HB.instance Definition _ A : HasPoint (list A) := HasPoint.Build (list A) nil. HB.instance Definition _ A : HasPoint Type := HasPoint.Build Type nat. HB.structure Definition Pointed := { T of HasPoint T }. HB.saturate (list _). Fail Check nat : Pointed.type. Fail Check bool : Pointed.type. Check (list unit : Pointed.type). Fail Check Type : Pointed.type. math-comp-hierarchy-builder-4d8a939/tests/short.v000066400000000000000000000016261521677141400220530ustar00rootroot00000000000000From Corelib Require Import ssreflect ssrfun. From HB Require Import structures. HB.mixin Record hasA T := { a : T }. #[short(type="aType", pack="AType")] HB.structure Definition A := {T of hasA T}. Check aType. HB.mixin Record hasB T := { b : T }. About hasB.type. #[short(type="bType", pack="BType")] HB.structure Definition B := {T of hasB T}. #[short(type="abType", pack="ABType")] HB.structure Definition AB := {T of hasA T & hasB T}. HB.factory Record hasAB T := { a : T; b : T }. HB.builders Context T & hasAB T. Definition xxx := ABType T (hasB.Build T b) (hasA.Build T a). HB.instance Definition _ := AB.copy T xxx. HB.end. About hasAB.type. HB.factory Definition hasA' T := hasA T. About hasA'.type. Section test. Variables (G : Prop) (P : AB.type -> G). Goal forall T (a b : T), G. Proof. move=> T a b. pose Ta := hasA.Build T a. pose Tb := hasB.Build T b. exact: P (ABType T Ta Tb). Qed. End test. math-comp-hierarchy-builder-4d8a939/tests/subtype.v000066400000000000000000000023051521677141400224020ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_inhab T := { default : T }. HB.structure Definition Inhab := { T of is_inhab T }. HB.mixin Record is_nontrivial T := { twodiff : forall x : T, exists y : T, ~~ (x = y) }. HB.structure Definition Nontrivial1 := { T of is_nontrivial T }. HB.structure Definition Nontrivial := { T of is_inhab T & is_nontrivial T }. Definition pred T := T -> Prop. #[key="sub_sort"] HB.mixin Record is_SUB (T : Type) (P : pred T) (sub_sort : Type) := SubType { val : sub_sort -> T; Sub : forall x, P x -> sub_sort; Sub_rect : forall K (_ : forall x Px, K (@Sub x Px)) u, K u; SubK : forall x Px, val (@Sub x Px) = x }. HB.structure Definition SUB (T : Type) (P : pred T) := { S of is_SUB T P S }. #[verbose] HB.structure Definition SubInhab (T : Type) P := { sT of is_inhab sT & is_SUB T P sT }. HB.structure Definition SubNontrivial T P := { sT of is_nontrivial sT & is_SUB T P sT }. #[key="sT"] HB.factory Record InhabForSub (T : Inhab.type) P (sT : Type) & SubNontrivial T P sT := {}. HB.builders Context (T : Inhab.type) P sT & InhabForSub T P sT. Axiom xxx : P (default : T). HB.instance Definition SubInhabMix := is_inhab.Build sT (Sub (default : T) xxx). HB.end. math-comp-hierarchy-builder-4d8a939/tests/test_CS_db_filtering.v000066400000000000000000000014311521677141400247620ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record base_m T := { A : T }. HB.structure Definition base := { T of base_m T }. HB.mixin Record child1_m T := { C1 : T }. HB.structure Definition child1 := { T of base T & child1_m T }. HB.mixin Record child2_m T := { C2 : T }. HB.structure Definition child2 := { T of base T & child2_m T }. Axiom ix : Type. Definition vec T := ix -> T. Section b. Variable T : base.type. HB.instance Definition v_base_m : base_m (vec T) := base_m.Build _ (fun _ => A). End b. Section c1. Variable T : child1.type. HB.instance Definition v_child1_m : child1_m (vec T) := child1_m.Build _ (fun _ => C1). End c1. Section c2. Variable T : child2.type. HB.instance Definition v_child2_m : child2_m (vec T) := child2_m.Build _ (fun _ => C2). End c2. math-comp-hierarchy-builder-4d8a939/tests/test_howto.v000066400000000000000000000003241521677141400231050ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record hasB T := Mixin { b : unit; }. HB.mixin Record hasA T := Mixin { a : bool; }. HB.structure Definition A := { T of hasA T}. HB.howto A.type. (* runs forever *)math-comp-hierarchy-builder-4d8a939/tests/test_synthesis_params.v000066400000000000000000000021101521677141400253340ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record IsDualPOrdered (d : unit) T := { le : T -> T -> bool; ge : T -> T -> bool }. HB.structure Definition POrder d := { T of IsDualPOrdered d T }. HB.factory Record IsPOrdered (d : unit) T := { le : T -> T -> bool }. HB.builders Context d T & IsPOrdered d T. HB.instance Definition _ := IsDualPOrdered.Build d T le le. HB.end. HB.mixin Record HasBottom d T & IsDualPOrdered d T := { bottom : T }. HB.structure Definition BPOrder d := { T of HasBottom d T & IsDualPOrdered d T }. HB.mixin Record HasTop d T & IsDualPOrdered d T := { top : T }. HB.structure Definition TPOrder d := { T of HasTop d T & IsDualPOrdered d T }. Definition dual (T : Type) := T. Definition dd (d:unit) : unit. exact d. Qed. HB.instance Definition _ d (T : POrder.type d) := IsDualPOrdered.Build (dd d) (dual T) (fun x y => @le d T y x) (fun x y => @le d T y x). HB.instance Definition _ d (T : TPOrder.type d) := HasBottom.Build (dd d) (dual T) (@top _ T). HB.instance Definition _ d (T : BPOrder.type d) := HasTop.Build (dd d) (dual T) (@bottom _ T). math-comp-hierarchy-builder-4d8a939/tests/two_hier.v000066400000000000000000000054611521677141400225350ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1 := { T of m1 T }. HB.structure Definition s2 := { T of m2 T }. HB.instance Definition nat_m1 := m1.Build nat 0. HB.instance Definition nat_m2 := m2.Build nat 1. (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2 (X : s2.type) : m2 (list X) := m2.Build (list X) (cons default2 nil). HB.structure Definition s3 := { T of m1 T & m2 T }. (* since we can preserve m1 and m2 with list, we can preserve s3 as well ! *) (* if we have a file A with definitions of S1 and S2, file B importing Awith definitions of instance nat_m1 and nat_m2 file C importing A with the definition of s3 in a file D that imports B and C if we call saturate_instance, we create the instance for s3. this example shows the need for a separate command *) Fail Check nat : s3.type. HB.saturate. Check nat : s3.type. (* since nat satisfies s3.type, so does list nat *) Check list nat : s3.type. Check list (list nat) : s3.type. Fail Check fun t : s1.type => (list t : s3.type). Fail Check fun t : s2.type => (list t : s3.type). Check fun t : s3.type => (list t : s3.type). HB.mixin Record m1' (P : s1.type) T := { f1 : P -> T }. HB.mixin Record m2' (P : s2.type) T := { f2 : P -> T }. (* since s1 only requires m1 there is a 1:1 correspondence between the structure s1 and the mixin m1 *) HB.structure Definition s1' P := { T of m1' P T }. HB.structure Definition s2' P := { T of m2' P T }. HB.instance Definition nat_m1' := m1'.Build nat nat (fun _ => 0). HB.instance Definition nat_m2' := m2'.Build nat nat (fun _ => 1). (* with the following example we want to show that list preserves the s1 structure ie. if x:s1.type then (list x):s1.type, in practice we can use this for the type of polynomials *) HB.instance Definition list_m1' (P : s1.type) (X : s1'.type P) : m1' P (list X) := m1'.Build P (list X) (fun x => cons (f1 x) nil). (* similarly list preserves s2 structure *) HB.instance Definition list_m2' (P : s2.type) (X : s2'.type P) : m2' P (list X) := m2'.Build P (list X) (fun x => cons (f2 x) nil). HB.structure Definition s3' (P : s3.type) := { T of m1' P T & m2' P T }. Fail Check nat : s3'.type _. HB.saturate. Check nat : s3'.type _. (* since nat satisfies s3'.type, so does list nat *) Check list nat : s3'.type _. Check Datatypes_list__canonical__two_hier_s3'. Check list (list nat) : s3'.type _.math-comp-hierarchy-builder-4d8a939/tests/type_of_exported_ops.v000066400000000000000000000015431521677141400251520ustar00rootroot00000000000000From HB Require Import structures. Definition comb A op := forall x : A, op (op x) = x. HB.mixin Record Foo A := { op : A -> A; ax : comb A op }. HB.structure Definition S := { A of Foo A }. Set Printing All. Lemma test1 : True. Proof. pose proof @ax as H. match goal with | H : forall x : S.type, comb (S.sort x) op |- _ => trivial | H : ?T |- _ => fail "type of ax not as nice as expected:" T end. Qed. HB.mixin Record HasMul T := { mul : T -> T -> T; mulC: forall x y : T, mul x y = mul y x; mulA: forall x y z : T, mul x (mul y z) = mul (mul x y) z; }. HB.structure Definition Mul := { T of HasMul T }. Lemma test2 : True. Proof. pose proof @mulA as H. match goal with | H : forall s : Mul.type, forall x y z : Mul.sort s, mul x (mul y z) = mul (mul x y) z |- _ => trivial | H : ?T |- _ => fail "type of mulA not as nice as expected:" T end. Qed. math-comp-hierarchy-builder-4d8a939/tests/unimported_irrelevant_class.v000066400000000000000000000006411521677141400265160ustar00rootroot00000000000000From HB Require Import structures. Module A. HB.mixin Record isA T := {}. HB.structure Definition A := {T of isA T}. End A. HB.mixin Record isB T := {}. HB.structure Definition B := {T of isB T}. Module Export C. Import A. HB.mixin Record isC T & A T & B T := {}. HB.structure Definition C := {T of isB T & isA T & isC T}. End C. (* Should not fail: A is irrelevant *) HB.instance Definition _ := isB.Build unit. math-comp-hierarchy-builder-4d8a939/tests/unimported_relevant_class.v000066400000000000000000000005531521677141400261650ustar00rootroot00000000000000From HB Require Import structures. Module A. HB.mixin Record isA T := {}. HB.structure Definition A := {T of isA T}. End A. Module Export B. Import A. HB.factory Record isB T := {}. HB.builders Context T & isB T. HB.instance Definition _ := isA.Build T. HB.end. End B. (* legitimate failure: A is relevant *) Fail HB.instance Definition _ := isB.Build unit. math-comp-hierarchy-builder-4d8a939/tests/unit/000077500000000000000000000000001521677141400214775ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests/unit/close_hole_term.v000066400000000000000000000016421521677141400250340ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. From Corelib Require Export Setoid. Elpi Query HB.instance lp:{{ X = app [{{list}}, Y_], % X needs to be typechecked here to get rid of the hole for the type of Y coq.typecheck X _ ok, abstract-holes.main X Z, std.assert! (Z = {{fun x => list x}}) "term badly closed" }}. Elpi Query HB.instance lp:{{ abstract-holes.main {{nat}} Z, std.assert! (Z = {{nat}}) "term badly closed" }}. Class Inj {A B} (R : relation A) (S : relation B) (f : A -> B) : Prop := inj x y : S (f x) (f y) -> R x y. Elpi Query HB.structure lp:{{ Y = {{Inj}}, %Inj has 5 implicit arguments saturate-type-constructor Y X, % X needs to be typechecked here to get rid of the holes of the types of its arguments coq.typecheck X _ ok, abstract-holes.main X Z, std.assert! (Z = {{ fun a b c d e => @Inj a b c d e }}) "term badly closed" }}. math-comp-hierarchy-builder-4d8a939/tests/unit/enrich_type.v000066400000000000000000000015561521677141400242060ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. From Corelib Require Export Setoid. Elpi Query HB.structure lp:{{ saturate-type-constructor {{nat}} X, std.assert! (X = {{nat}}) "wrong enriched type" }}. Elpi Query HB.structure lp:{{ saturate-type-constructor {{list}} X, std.assert! (X = app [{{list}}, Y_]) "wrong enriched type" }}. Elpi Query HB.structure lp:{{ Y = (x \ (y \ {{(prod (list lp:x) (list lp:y))}})), saturate-type-constructor (Y _ _) X, std.assert! (X = (app [{{prod}}, (app[{{list}},X1_]), app[{{list}},C_]])) "wrong enriched type" }}. Class Inj {A B} (R : relation A) (S : relation B) (f : A -> B) : Prop := inj x y : S (f x) (f y) -> R x y. Elpi Query HB.structure lp:{{ saturate-type-constructor {{Inj}} X, std.assert! (X = app [(global (const Inj_)), A_, B_, R_, S_, F_]) "wrong enriched type" }}. math-comp-hierarchy-builder-4d8a939/tests/unit/mixin_src_has_mixin_instance.v000066400000000000000000000015131521677141400276040ustar00rootroot00000000000000From HB Require Import structures. From elpi Require Import elpi. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.structure Definition s1 := { T of m1 T }. HB.instance Definition i1 (X : s1.type) : m1 (list X) := m1.Build (list X) (cons default1 nil). HB.instance Definition nat_m1 : m1 nat := m1.Build nat 1. HB.instance Definition nat_m2 : m2 nat := m2.Build nat 1. Elpi Query HB.instance lp:{{ mixin-src->has-mixin-instance (mixin-src {{nat}} M1_ {{nat_m1}}) Y, Y = has-mixin-instance (cs-gref {{:gref nat}}) {{:gref m1.phant_axioms}} {{:gref nat_m1}}. }}. Section Test. Variable X:s1.type. Elpi Query HB.instance lp:{{ mixin-src->has-mixin-instance (mixin-src {{list X}} M1_ {{i1 X}}) Y, Y = has-mixin-instance (cs-gref {{:gref list}}) {{:gref m1.phant_axioms}} {{:gref i1}}. }}. End Test. math-comp-hierarchy-builder-4d8a939/tests/unit/mk_src_map.v000066400000000000000000000016551521677141400240100ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.mixin Record is_foo' P A := { op : P -> A -> A }. HB.instance Definition list_foo P := is_foo.Build P (list P) (fun _ x => x). HB.instance Definition list_foo' P A := is_foo.Build P (list A) (fun _ x => x). Check list_foo'. Check list_foo. Elpi Query HB.structure lp:{{ has-mixin-instance->mixin-src (has-mixin-instance (cs-gref{{:gref list}}) {{:gref is_foo.axioms_}} {{:gref list_foo}}) MS, MS = (pi a b \ mixin-src (app [{{list}}, b]) ({{:gref is_foo.axioms_}}) (app [{{list_foo}}, a]) :- [coq.unify-eq a b ok]) }}. Elpi Query HB.structure lp:{{ has-mixin-instance->mixin-src (has-mixin-instance (cs-gref{{:gref list}}) {{:gref is_foo.axioms_}} {{:gref list_foo'}}) MS', MS' = (pi p a b \ mixin-src (app [{{list}}, b]) {{:gref is_foo.axioms_}} (app [{{list_foo'}}, p,a]) :- [coq.unify-eq a b ok]). }}.math-comp-hierarchy-builder-4d8a939/tests/unit/struct.v000066400000000000000000000023341521677141400232140ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record m1 T := { default1 : T }. HB.mixin Record m2 T := { default2 : T }. HB.mixin Record is_foo P A := { op : P -> A -> A }. HB.structure Definition foo P := { A of is_foo P A}. HB.structure Definition foo1 := { A of is_foo (option nat) A & m1 A}. Elpi Query HB.structure lp:{{ std.findall (has-mixin-instance _ _ _) H_ }}. (* here we don't have any declared instances but a clause is still created by the system : has-mixin-instance (cs-gref (const «eta»)) (indt «is_foo.axioms_») (const «struct_foo1__to__struct_is_foo») struct_foo1__to__struct_is_foo is an instance created by the system upon structure declaration to allow coercions from foo1 to other structures with the mixin is_foo. *) Print struct_foo1__to__struct_foo. (* its type is forall A : foo1.type, is_foo.axioms_ (option nat) (eta A)) which means it can't serve as a coercion for foo2 or foo3, however foo3 can still be declared because it has another mixin, while foo2 can't because it has the exact same mixins than foo *) Fail HB.structure Definition foo2 := { A of is_foo bool A}. HB.structure Definition foo3 := { A of is_foo bool A & m2 A}. Fail HB.structure Definition fooj := { A of foo1 A & foo3 A}. math-comp-hierarchy-builder-4d8a939/tests_stdlib/000077500000000000000000000000001521677141400220615ustar00rootroot00000000000000math-comp-hierarchy-builder-4d8a939/tests_stdlib/about.v000066400000000000000000000023521521677141400233640ustar00rootroot00000000000000From Coq Require Import ZArith ssrfun ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.instance Definition _ := AddAG_of_TYPE.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l. HB.instance Definition _ := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. (* mixin *) HB.about AddMonoid_of_TYPE. (* mixin constructor *) HB.about AddMonoid_of_TYPE.Build. (* structure *) HB.about AddAG.type. (* class *) HB.about AddMonoid. (* factory *) HB.about Ring_of_AddAG. (* factory constructor *) HB.about Ring_of_AddAG.Build. (* operation *) HB.about add. (* canonical proj/value *) HB.about AddAG.sort. (* canonical value *) HB.about Z. (* coercion *) HB.about hierarchy_5_Ring_class__to__hierarchy_5_SemiRing_class. HB.about hierarchy_5_Ring__to__hierarchy_5_SemiRing. (* builder *) HB.about Builders_40.hierarchy_5_Ring_of_AddAG__to__hierarchy_5_BiNearRing_of_AddMonoid. HB.locate BinNums_Z__canonical__hierarchy_5_AddAG. (* Test minimally qualified names *) Module Import hierarchy_5. Module AddComoid. End AddComoid. End hierarchy_5. HB.about Z. math-comp-hierarchy-builder-4d8a939/tests_stdlib/exports.v000066400000000000000000000055361521677141400237650ustar00rootroot00000000000000From Coq Require Import ssreflect ssrfun ZArith. From HB Require Import structures. Module Enclosing. (**************************************************************************) (* Stage 0: +Ring+ *) (**************************************************************************) HB.mixin Record Ring_of_TYPE A := { zero : A; one : A; add : A -> A -> A; opp : A -> A; mul : A -> A -> A; addrA : associative add; addrC : commutative add; add0r : left_id zero add; addNr : left_inverse zero opp add; mulrA : associative mul; mul1r : left_id one mul; mulr1 : right_id one mul; mulrDl : left_distributive mul add; mulrDr : right_distributive mul add; }. #[mathcomp] HB.structure Definition Ring := { A of Ring_of_TYPE A }. (* Notations *) Module RingExports. Declare Scope hb_scope. Delimit Scope hb_scope with G. Local Open Scope hb_scope. Notation "0" := zero : hb_scope. Notation "1" := one : hb_scope. Infix "+" := (@add _) : hb_scope. Notation "- x" := (@opp _ x) : hb_scope. Infix "*" := (@mul _) : hb_scope. Notation "x - y" := (x + - y) : hb_scope. End RingExports. HB.export RingExports. (* Theory *) Section Theory. Local Open Scope hb_scope. Variable R : Ring.type. Implicit Type (x : R). Lemma addr0 : right_id (@zero R) add. Proof. by move=> x; rewrite addrC add0r. Qed. HB.export addr0. Lemma addrN : right_inverse (@zero R) opp add. Proof. by move=> x; rewrite addrC addNr. Qed. Lemma subrr x : x - x = 0. Proof. by rewrite addrN. Qed. Lemma addrNK x y : x + y - y = x. Proof. by rewrite -addrA subrr addr0. Qed. End Theory. HB.mixin Record Dummy T := { u : unit }. HB.structure Definition URing := { R of Ring R & Dummy R }. HB.factory Record dummy R & Ring R := {}. HB.builders Context T & dummy T. HB.instance Definition _ := Dummy.Build T tt. Definition addrNK := addrNK. HB.export addrNK. HB.end. Module Import Instances. #[export] HB.instance Definition Z_ring_axioms := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. Module Exports. HB.reexport Instances. End Exports. End Instances. Module Exports. #[verbose] HB.reexport. End Exports. Module ExportsOnlyInstance. Export Instances.Exports. End ExportsOnlyInstance. End Enclosing. Module Test1. (* We miss the coercions, canonical and elpi metadata *) Fail Check forall (R : Enclosing.Ring.type) (x : R), x = x. Fail Check 0%G. Fail Check addr0. Export Enclosing.Exports. Check forall (R : Enclosing.Ring.type) (x : R), x = x. Check 0%G. Example test1 (m n : Z) : ((m + n) - n + 0 = m)%G. Proof. by rewrite addrNK addr0. Qed. End Test1. Module Test2. Fail Check Enclosing.zero : Z. Export Enclosing.ExportsOnlyInstance. Check Enclosing.zero : Z. Fail Check 0%G. (* notation not there *) End Test2. math-comp-hierarchy-builder-4d8a939/tests_stdlib/exports2.v000066400000000000000000000001741521677141400240400ustar00rootroot00000000000000From HB Require Import structures. From HB Require tests_stdlib.exports. Import exports.Enclosing. #[verbose] HB.reexport. math-comp-hierarchy-builder-4d8a939/tests_stdlib/funclass.v000066400000000000000000000027661521677141400241010ustar00rootroot00000000000000From HB Require Import structures. HB.mixin Record has_assoc T (F : T -> T -> T) := { assoc : forall x y z : T , F x (F y z) = F (F x y) z; }. HB.structure Definition Magma T := { F of has_assoc T F }. HB.mixin Record has_neutral T (F : T -> T -> T) := { id : T; idl : forall x : T , F id x = x; idr : forall x : T , F x id = x; }. HB.structure Definition Monoid T := { F of Magma T F & has_neutral T F }. About id. Require Import Arith ssreflect. HB.instance Definition x1 := has_assoc.Build nat plus Nat.add_assoc. Lemma plus_O_r x : x + 0 = x. Proof. by rewrite -plus_n_O. Qed. HB.instance Definition x2 := has_neutral.Build nat plus 0 plus_O_n plus_O_r. Check Monoid.on plus. Lemma test x : x + 0 = x. Proof. by rewrite idr. Qed. HB.factory Record MOT T (F : T -> T -> T) := { assoc : forall x y z : T , F x (F y z) = F (F x y) z; id : T; idl : forall x : T , F id x = x; commid : forall x : T , F x id = F id x; }. HB.builders Context T F & MOT T F. HB.instance Definition x3 := has_assoc.Build T F assoc. Lemma myidr x : F x id = x. Proof. by rewrite commid idl. Qed. HB.instance Definition x4 := has_neutral.Build T F id idl myidr. HB.end. HB.instance Definition x5 := MOT.Build nat mult Nat.mul_assoc 1 Nat.mul_1_l (fun x => Nat.mul_comm x 1). Check Monoid.on mult. HB.mixin Record silly (T1 : Type) (F : Monoid.type T1) (T : Type) := { xx : T }. HB.structure Definition wp T (F : Monoid.type T) := { A of silly T F A }. #[skip="8.11"] HB.check (forall w : wp.type _ mult, w = w). math-comp-hierarchy-builder-4d8a939/tests_stdlib/howto.v000066400000000000000000000012731521677141400234130ustar00rootroot00000000000000From Coq Require Import ZArith ssrfun ssreflect. From HB Require Import structures. From HB Require Import demo1.hierarchy_5. HB.howto Ring.type. HB.howto Ring.type 2. HB.howto Z Ring.type. HB.howto Z Ring.type 2. Fail HB.howto Z Ring.type 0. HB.howto AddComoid.type Ring.type. HB.instance Definition _ := AddAG_of_TYPE.Build Z 0%Z Z.add Z.opp Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l. HB.howto Z Ring.type. HB.howto AddAG.type Ring.type. HB.instance Definition _ := Ring_of_TYPE.Build Z 0%Z 1%Z Z.add Z.opp Z.mul Z.add_assoc Z.add_comm Z.add_0_l Z.add_opp_diag_l Z.mul_assoc Z.mul_1_l Z.mul_1_r Z.mul_add_distr_r Z.mul_add_distr_l. HB.howto Z Ring.type.