Ignore:
Timestamp:
May 2, 2023, 3:44:31 AM (15 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ast-experimental, master
Children:
0c840fc
Parents:
1ab773e0
Message:

current progress

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/SatisfyAssertions.cpp

    r1ab773e0 r46da46b  
    1616#include "SatisfyAssertions.hpp"
    1717
     18#include <iostream>
    1819#include <algorithm>
    1920#include <cassert>
     
    4243#include "SymTab/Mangler.h"
    4344
     45
     46
    4447namespace ResolvExpr {
    4548
     
    6265                        ast::AssertionSet && h, ast::AssertionSet && n, ast::OpenVarSet && o, ast::UniqueId rs )
    6366                : cdata( c ), adjType( at ), env( std::move( e ) ), have( std::move( h ) ),
    64                   need( std::move( n ) ), open( std::move( o ) ), resnSlot( rs ) {}
     67                  need( std::move( n ) ), open( std::move( o ) ), resnSlot( rs ) {
     68                        if (!have.empty()) {
     69                                std::cerr << c.id->location << ':' << c.id->name << std::endl;
     70                        }
     71                  }
    6572        };
    6673
     
    136143        };
    137144
    138         /// Adds a captured assertion to the symbol table
    139         void addToSymbolTable( const ast::AssertionSet & have, ast::SymbolTable & symtab ) {
    140                 for ( auto & i : have ) {
    141                         if ( i.second.isUsed ) { symtab.addId( i.first->var ); }
    142                 }
    143         }
     145
    144146
    145147        /// Binds a single assertion, updating satisfaction state
     
    152154                        "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    153155
    154                 ast::Expr * varExpr = match.cdata.combine( cand->expr->location, cand->cvtCost );
     156                ast::Expr * varExpr = match.cdata.combine( cand->expr->location, cand->cost );
    155157                varExpr->result = match.adjType;
    156158                if ( match.resnSlot ) { varExpr->inferred.resnSlots().emplace_back( match.resnSlot ); }
     
    162164
    163165        /// Satisfy a single assertion
    164         bool satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat, bool allowConversion = false, bool skipUnbound = false) {
     166        bool satisfyAssertion( ast::AssertionList::value_type & assn, SatState & sat, bool skipUnbound = false) {
    165167                // skip unused assertions
     168                static unsigned int cnt = 0;
    166169                if ( ! assn.second.isUsed ) return true;
    167170
     171                if (assn.first->var->name[1] == '|') std::cerr << ++cnt << std::endl;
     172
    168173                // find candidates that unify with the desired type
    169                 AssnCandidateList matches;
     174                AssnCandidateList matches, inexactMatches;
    170175
    171176                std::vector<ast::SymbolTable::IdData> candidates;
     
    209214
    210215                        ast::OpenVarSet closed;
    211                         findOpenVars( toType, newOpen, closed, newNeed, have, FirstClosed );
    212                         findOpenVars( adjType, newOpen, closed, newNeed, have, FirstOpen );
    213                         if ( allowConversion ) {
     216                        // findOpenVars( toType, newOpen, closed, newNeed, have, FirstClosed );
     217                        findOpenVars( adjType, newOpen, closed, newNeed, have, newEnv, FirstOpen );
     218                        ast::TypeEnvironment tempNewEnv {newEnv};
     219
     220                        if ( unifyExact( toType, adjType, tempNewEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) {
     221                                // set up binding slot for recursive assertions
     222                                ast::UniqueId crntResnSlot = 0;
     223                                if ( ! newNeed.empty() ) {
     224                                        crntResnSlot = ++globalResnSlot;
     225                                        for ( auto & a : newNeed ) { a.second.resnSlot = crntResnSlot; }
     226                                }
     227
     228                                matches.emplace_back(
     229                                        cdata, adjType, std::move( tempNewEnv ), std::move( have ), std::move( newNeed ),
     230                                        std::move( newOpen ), crntResnSlot );
     231                        }
     232                        else if ( matches.empty() ) {
     233                                // restore invalidated env
     234                                // newEnv = sat.cand->env;
     235                                // newNeed.clear();
    214236                                if ( auto c = commonType( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) {
    215237                                        // set up binding slot for recursive assertions
     
    220242                                        }
    221243
    222                                         matches.emplace_back(
     244                                        inexactMatches.emplace_back(
    223245                                                cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ),
    224246                                                std::move( newOpen ), crntResnSlot );
    225247                                }
    226248                        }
    227                         else {
    228                                 if ( unifyExact( toType, adjType, newEnv, newNeed, have, newOpen, WidenMode {true, true}, sat.symtab ) ) {
    229                                         // set up binding slot for recursive assertions
    230                                         ast::UniqueId crntResnSlot = 0;
    231                                         if ( ! newNeed.empty() ) {
    232                                                 crntResnSlot = ++globalResnSlot;
    233                                                 for ( auto & a : newNeed ) { a.second.resnSlot = crntResnSlot; }
    234                                         }
    235 
    236                                         matches.emplace_back(
    237                                                 cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ),
    238                                                 std::move( newOpen ), crntResnSlot );
    239                                 }
    240                         }
    241249                }
    242250
    243251                // break if no satisfying match
     252                if ( matches.empty() ) matches = std::move(inexactMatches);
    244253                if ( matches.empty() ) return false;
    245254
     
    252261                // otherwise bind unique match in ongoing scope
    253262                AssnCandidate & match = matches.front();
    254                 addToSymbolTable( match.have, sat.symtab );
     263                // addToSymbolTable( match.have, sat.symtab );
    255264                sat.newNeed.insert( match.need.begin(), match.need.end() );
    256265                sat.cand->env = std::move( match.env );
     
    435444                // for each current mutually-compatible set of assertions
    436445                for ( SatState & sat : sats ) {
    437                         bool allowConversion = false;
    438446                        // stop this branch if a better option is already found
    439447                        auto it = thresholds.find( pruneKey( *sat.cand ) );
     
    448456                                for ( auto & assn : sat.need ) {
    449457                                        // fail early if any assertion is not satisfiable
    450                                         if ( ! satisfyAssertion( assn, sat, allowConversion, !next.empty() ) ) {
     458                                        if ( ! satisfyAssertion( assn, sat, !next.empty() ) ) {
    451459                                                next.emplace_back(assn);
    452460                                                // goto nextSat;
     
    457465                                // fail if nothing resolves
    458466                                else if (next.size() == sat.need.size()) {
    459                                         if (allowConversion) {
     467                                        // if (allowConversion) {
    460468                                                Indenter tabs{ 3 };
    461469                                                std::ostringstream ss;
     
    467475                                                errors.emplace_back( ss.str() );
    468476                                                goto nextSat;
    469                                         }
    470 
    471                                         else {
    472                                                 allowConversion = true;
    473                                                 continue;
    474                                         }
    475                                 }
    476                                 allowConversion = false;
     477                                        // }
     478
     479                                        // else {
     480                                        //      allowConversion = true;
     481                                        //      continue;
     482                                        // }
     483                                }
    477484                                sat.need = std::move(next);
    478485                        }
     
    528535                                                sat.cand->expr, std::move( compat.env ), std::move( compat.open ),
    529536                                                ast::AssertionSet{} /* need moved into satisfaction state */,
    530                                                 sat.cand->cost, sat.cand->cvtCost );
     537                                                sat.cand->cost );
    531538
    532539                                        ast::AssertionSet nextNewNeed{ sat.newNeed };
     
    541548                                        for ( DeferRef r : compat.assns ) {
    542549                                                AssnCandidate match = r.match;
    543                                                 addToSymbolTable( match.have, nextSymtab );
     550                                                // addToSymbolTable( match.have, nextSymtab );
    544551                                                nextNewNeed.insert( match.need.begin(), match.need.end() );
    545552
Note: See TracChangeset for help on using the changeset viewer.